Reputation: 682
I've been experimenting with css pseudo classes and pseudo elements and I discover something that I have not been able to get around.
Consider the following html input field:
<input type="number" value="1" min="1" max="1000" step="1" pattern="\d" /><span></span>
In order to achieve 3 states: empty, valid and invalid. I'm using the ::after pseudo element (applied to the span adjacent to the input) to add a checkmark when the value of the filed is valid, and an X when the value is invalid.
I'm using the pseudo classes :valid and :invalid and it seems that when an input field is empty (value="") its state is also valid.
The CSS in question is as follows:
.v3_forms input[value=""] + span::after {
content: "";
}
.v3_forms input:valid + span::after {
content: "\2713";
color: limegreen;
}
.v3_forms input:invalid + span::after {
content: "X";
color: #ce0000;
}
For what I'm able to tell, after clearing the value in the browser, the second css rules takes precedence, even though the specificity is the same.
I tested the selectors here: specificity calculator and it seems that attributes and pseudo classes have the same weight.
Upvotes: 8
Views: 4303
Reputation: 21191
An empty string is, by default, a valid value:
User agents should allow the user to set the value to the empty string *.
If you want to require a value for the field, you need to add the required
attribute:
.v3_forms input[value=""] + span::after {
content: "";
}
.v3_forms input:valid + span::after {
content: "\2713";
color: limegreen;
}
.v3_forms input:invalid + span::after {
content: "X";
color: #ce0000;
}
<div class="v3_forms">
<input type="number" value="1" min="1" max="1000" step="1" pattern="\d" required /><span></span>
</div>
This addresses the specific example in your question, but the same will hold true for any of the <input />
elements that accept user input.
*See the whatwg reference.
Upvotes: 12