Modern CSS3 Selectors: Advanced Pseudo-classes and Functional Enhancements
:is() — Simplified Selector Grouping
The :is() pseudo-class accepts a list of selectors and matches any element that would be selected by atleast one of the provided selectors. This reduces redundancy when styling elements with similar behaviors across different parent containers.
Before:
header p:hover,
main p:hover,
footer p:hover {
color: red;
cursor: pointer;
}
After:
:is(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
This approach improves maintainability and readability.
:where() — Zero-Priority Selector Grouping
Similar to :is(), :where() takes a selector list and matches elements that satisfy any of them. The key distinction is that :where() always has a specificity of zero, making it useful for overriding styles without increasing priority.
Example:
<div>
<p>where & is test</p>
</div>
:is(div) p {
color: red;
}
:where(div) p {
color: green;
}
Despite :where(div) p being defined later, the text remains red because :is(div) inherits the specificity of its internal selector (in this case, div), while :where(div) effectively contributes no specificity.
:not() — Negation Pseudo-class
The :not() pseudo-class selects all elements that do not match the given selector(s). It’s commonly used to exclude specific elements from a style rule.
Example:
<div class="a">div.a</div>
<div class="b">div.b</div>
<div class="c">div.c</div>
<div class="d">div.d</div>
div:not(.b) {
color: red;
}
This applies red text to all div elements except those with the class .b.
Note: Inherited properties may not behave as expected if applied via
:not()due to cascading rules.
:has() — Parent-Based Conditional Selection
:has() enables selection based on the presence of descendant or sibling elements. It acts as a conditional check within the parent context.
Descendant Check:
<div>
<p>div -- p</p>
</div>
<div>
<p class="g-test-has">div -- p.has</p>
</div>
<div>
<p>div -- p</p>
</div>
div:has(.g-test-has) {
border: 1px solid #000;
}
Only the div containing a child with class .g-test-has receives the border.
Sibling Check (Adjacent):
<div class="has-test">div + p</div>
<p>p</p>
<div class="has-test">div + h1</div>
<h1>h1</h1>
<div class="has-test">div + h2</div>
<h2>h2</h2>
.has-test:has(+ h2) {
margin-left: 24px;
border: 1px solid #000;
}
Applies styles only to .has-test divs immediately followed by an h2 element.
Caution: Browser support for
:has()is limited; use cautiously in production.
:within — Last Child Matching
:within selects the final direct child of a container, enabling targeted styling of last elements in a sequence.
Example:
<div class="within-test">
<p>within-test</p>
<p>within-test</p>
<p>within-test</p>
</div>
.within-test:within {
border: 1px solid #000;
}
Applies the border only to the last <p> inside .within-test.
:focus-within — Focus Context Detection
:focus-within targets an element if it or any of its descendants currently has focus.
Example:
<div class="focus-within-test">
<p>focus-within-test</p>
<p>focus-within-test</p>
<p>focus-within-test</p>
</div>
.focus-within-test:focus-within {
border: 1px solid #000;
}
When any nested <p> receives keyboard focus, the entire container gets styled.
::first-letter — Styling First Character
The ::first-letter pseudo-element targets the first letter of a block-level or inline-block element.
Example:
<p class="first-letter-test">first-letter-test</p>
.first-letter-test::first-letter {
font-size: 24px;
color: red;
}
This allows typographic enhancements like drop caps.
::selection — Customizing Highlighted Text
::selection styles the portion of text that is selected by the user.
Example:
<p class="selection-test">selection-test</p>
.selection-test::selection {
background-color: red;
color: #fff;
}
Improves UX by customizing the appearance of highlighted content.
For further exploration, see: https://zhuanlan.zhihu.com/p/516155516