According to the comment above, it seems that your selector is not correct. In your code, the label element comes before the input element and has the required attribute assigned to it. Therefore, using the plus sign "+" in your CSS rule will fail to target the label you intend to style. Instead, if there is a following label (which belongs to a different element), the selector will match and apply styles there.
The initial snippet mirrors your code with a similar selector, resulting in the following label being colored yellow instead of the intended one.
:required + label{background:yellow}
:required + label:after{content:'*';color:red}
<label for="username">Username</label>
<input type="text" name="username" required />
<label for="password">Password</label>
<input type="password" name="password" required />
However, by rearranging the order of the label and input elements, you can see the text appearing below the input element, which may not be the desired layout but demonstrates how the selector now correctly applies styles to the right element.
:required + label{background:yellow}
:required + label:after{content:'*';color:red}
<input type="text" name="username" required />
<label for="username">Username</label>
<input type="password" name="password" required />
<label for="password">Password</label>
If you want to position the pseudo content above the input element, you can experiment with a negative margin as a workaround – although it's not the most elegant solution, it somewhat gets the job done.
:required + label:after{
content:"*";
color:red;
position:relative;
top:-2.5rem;
margin:0 0 0 0.5rem;
}
label:before{
content:attr(for);
position:relative;
top:-2.5rem;
z-index:2;
text-transform:capitalize;
}
label{display:block}
input{margin:2rem 0 0 0}
<input type="text" name="username" required />
<label for="username"></label>
<input type="password" name="password" required />
<label for="password"></label>