CSS :nth-child(of S) - Filtered Positional Selection
Learn the new :nth-child(An+B of S) syntax to count only elements that match a filter selector. Skip hidden items, target visible cards, and handle dynamic lists cleanly.
Detailed Explanation
The of S Argument
Classic :nth-child(2) counts every sibling regardless of type or class. The Selectors Level 4 syntax :nth-child(An + B of S) restricts the count to siblings matching selector S:
/* Every other VISIBLE list item, ignoring hidden ones */
li:nth-child(odd of :not(.hidden)) {
background: #fafafa;
}
Without the of clause, hidden items still occupy positions in the count, which breaks zebra striping the moment one row is filtered out.
Practical Example: Searchable Lists
When users filter a result list with .hidden toggles, you want the visible rows to keep alternating colors:
<ul class="results">
<li>Alpha</li>
<li class="hidden">Beta</li>
<li>Gamma</li>
<li>Delta</li>
</ul>
.results li:nth-child(even of :not(.hidden)) {
background: #f5f5f5;
}
Alpha = position 1, Gamma = position 2 (even → striped), Delta = position 3.
Difference From :nth-of-type()
:nth-of-type() is hard-coded to filter by element tag. :nth-child(... of S) lets you filter by any selector — class, attribute, pseudo-class, or compound. It's strictly more general.
Specificity
The specificity is the base specificity of the pseudo-class plus the most specific selector inside the of clause, just like :is(). So :nth-child(2 of .row) has specificity (0, 2, 0).
Browser Support
Safari 9+, Chrome 111+ (Mar 2023), Firefox 113+ (May 2023). Provide a graceful base style for older browsers since the rule is silently ignored when unsupported.
Use Case
Use the of-filter syntax for any list whose items can be hidden or filtered: searchable tables, faceted product grids, filterable galleries. It's the cleanest way to keep zebra striping or N-th-item highlights stable as items toggle in and out of view.