Custom Selectors
CSS custom selectors, @custom-selector, and extending selector patterns.
Overview
Custom selectors extend CSS selector capabilities.
Key Concepts
- @custom-selector — Define custom selectors
- :--custom — Custom pseudo-class syntax
- Selector patterns — Reusable patterns
- @scope — Scoped selectors
- Nesting — Nested selectors
Code Examples
/* Custom selector (proposal) */
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:--heading {
font-weight: bold;
line-height: 1.2;
}
:--heading:first-child {
margin-top: 0;
}
/* Custom interactive states */
@custom-selector :--interactive a, button, [role="button"];
:--interactive {
cursor: pointer;
transition: all 0.2s ease;
}
:--interactive:hover {
opacity: 0.8;
}
:--interactive:focus-visible {
outline: 2px solid var(--primary);
}
/* Nesting selectors */
.card {
& .title {
font-size: 1.5rem;
&:hover {
color: var(--primary);
}
}
& .content {
color: #666;
& p {
margin-bottom: 1rem;
}
}
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
}
/* :is() and :where() */
:is(h1, h2, h3) {
font-weight: bold;
}
:where(.button, .link) {
cursor: pointer;
transition: all 0.2s ease;
}
/* :has() selector */
.form-group:has(:invalid) {
border-color: red;
}
.card:has(img) {
display: grid;
grid-template-columns: 200px 1fr;
}
/* Logical selectors */
.item:first-child:last-child {
/* Only child */
}
.item:not(:last-child)::after {
content: ',';
}
/* Attribute selectors */
[data-theme="dark"] {
--bg: #1a1a1a;
--text: #ffffff;
}
[data-type^="icon-"]::before {
content: attr(data-type);
}
[href$=".pdf"]::after {
content: ' (PDF)';
}
/* State selectors */
.input:is(:focus, :hover) {
border-color: var(--primary);
}
.checkbox:checked + label {
font-weight: bold;
}
Practice
Refactor CSS to use custom selectors and modern patterns.