๐ŸŽ›๏ธ CSS

Advanced CSS Selectors โ€” :has, :is, :where and :not in Practice

๐Ÿ“… Jul 3, 2026 โฑ 3 min read

Four modern selectors eliminate whole categories of JavaScript and class-juggling.

:has() โ€” the parent selector (finally!)

/* card that CONTAINS an image gets different padding */
.card:has(img) { padding: 0; }

/* form label turns red when ITS input is invalid */
label:has(+ input:user-invalid) { color: #ef4444; }

/* page freezes scrolling when a modal is open โ€” no JS! */
body:has(dialog[open]) { overflow: hidden; }

:is() โ€” stop repeating yourself

/* before */
article h1, article h2, article h3 { margin-top: 2rem; }
/* after */
article :is(h1, h2, h3) { margin-top: 2rem; }

:where() โ€” same, but zero specificity

Perfect for resets and libraries: :where(ul, ol) { margin: 0 } is trivially overridable by any user class โ€” no specificity fights.

:not() with lists

button:not(.primary, .danger) { background: gray; }
li:not(:last-child) { border-bottom: 1px solid #eee; }

All four work in every modern browser. Full selector reference: Complete CSS Guide ยง02.

โ† All Articles