A Practical CSS Selectors Cheat Sheet

CSS selectors go far beyond classes and IDs — knowing the less common ones regularly eliminates the need for extra classes or JavaScript entirely.

/* Combinators */
.parent > .child { }        /* direct child only */
.sibling + .next { }        /* immediately following sibling */
.sibling ~ .later { }       /* any following sibling */

/* Attribute selectors */
input[type="email"] { }
a[href^="https://"] { }     /* starts with */
a[href$=".pdf"] { }         /* ends with */
[class*="icon-"] { }        /* contains */

/* Structural pseudo-classes */
li:nth-child(odd) { }
li:first-of-type { }
p:not(.excluded) { }

/* State pseudo-classes */
input:focus-visible { }     /* keyboard focus only, not mouse clicks */
button:disabled { }
li:has(> .badge) { }        /* parent selector - finally, in modern browsers */

:has() is genuinely new capability — CSS never had a way to style a parent based on its children until relatively recently, and it eliminates a lot of JavaScript that previously existed solely to add a class based on child content.