CSS recently added the pseudo-classes :where()
and :is()
and I don't understand when to use which. Both can be used to select multiple elements. Here is a snippet where the same is achieved with both pseudo-classes:
span {
display: inline-block;
height: 100px;
width: 100px;
background-color: grey;
margin-bottom: 10px;
}
:is(.span1-1, .span1-2):hover {
background-color: firebrick;
}
:where(.span2-1, .span2-2):hover {
background-color: teal;
}
<span class="span1-1"></span>
<span class="span1-2"></span>
<br>
<span class="span2-1"></span>
<span class="span2-2"></span>
Can someone give an example where they behave differently from each other?
:is
vs :where
for those unfamiliar with CSS specificity:Specificity is written as 3 numbers, and is of the form ID-CLASS-TYPE
For example:
#thing .my-class div
has specificity 1-1-1
#thing .my-class div:hover
has specificity 1-1-2
(pseudo classes are considered a type)
.my-class .my-other-class
has specificity 0-2-0
#thing
has specificity 1-0-0
div
has specificity 0-0-1
To determine CSS rule priority, the specificities of rules are compared. Each of the 3 numbers are compared against other rules, letting the left-most comparison win.
For example, 0-2-0
wins against 0-1-3
, and 1-0-0
wins against 0-2-0
.
Now, to answer the question, :is
is useful to avoid repetition, so that you can write the rule ul li, ol li
as :is(ul, ol) li
Note that :is
is not itself counted as a pseudo-class for the purposes of calculating the specificity of the rule.
:where
lets you do exactly the same thing as :is
, except the rules mentioned inside the :where()
parentheses are not counted towards a rule's specificity calculation.
For example, :is(ul, ol) li
has specificity 0-0-2
, but :where(ul, ol) li
has specificity 0-0-1
.
You will only need to worry about your choice of where
vs is
if you find yourself in a situation where you need to consider the priorities of two similar CSS rules.
Note that any use of !important
will take priority over any specificity comparisons.