Leverage the recent functional pseudo-classes to select based on content, group selectors without inflating specificity, and target complex patterns.
Open this lesson in Kodokon:is() and :where() both group selectors, but they diverge on one decisive point: specificity. :is(nav, .menu, #main a) takes the specificity of its strongest argument (here the ID), even if nav is the one that matches. :where() has a specificity of zero, whatever its arguments. Practical consequence: :where() is the ideal tool for resets and a design system's default styles, which any simple class selector can then override without a fight.
:where(h1, h2, h3, h4) {
margin-block: 0;
line-height: 1.2;
}
:is(article, aside, section) :is(h2, h3) {
font-family: var(--font-heading);
}
.prose :is(ul, ol) li + li {
margin-top: 0.5em;
}:has() finally reverses the reading direction: the selector targets the host element, not what it contains. .card:has(> img) selects the card that has an image as a direct child. Combined with state pseudo-classes, it lets information flow upwards without JavaScript: styling a label when its field is invalid, a form when a field has focus, a table row when its checkbox is checked.
.field:has(input:invalid:not(:focus)) label {
color: #dc2626;
}
.card:has(> img) {
padding-top: 0;
}
tr:has(input[type="checkbox"]:checked) {
background: #eef2ff;
}On :nth-child(), two skills to consolidate. First, reading An+B formulas: 2n (even), 2n+1 (odd), -n+3 (the first three), n+4 (from the fourth to the end); the range "from the 2nd to the 5th" is written by combining :nth-child(n+2):nth-child(-n+5). Second, the more recent of S syntax: :nth-child(2n of .visible) counts only among the children that match .visible, whereas .visible:nth-child(2n) counts all children and then filters - two very different results as soon as other elements are interleaved.
tr:nth-child(odd) {
background: #fafafa;
}
li:nth-child(-n + 3) {
font-weight: 600;
}
li:nth-child(n + 2):nth-child(-n + 5) {
border-top: 1px solid #e5e7eb;
}
.row:nth-child(2n of .visible) {
background: #eef2ff;
}:where(#main, .nav, a)?.card:has(> img) select?li elements carry .visible, what does li:nth-child(2n of .visible) do?li elements of the list that also have the .visible classli, counting only the li.visible elementsli elements and then adds the .visible class to them