Skip to content

CSS Selectors Explained

Every common CSS selector, grouped by family: basic, combinators, pseudo-classes, pseudo-elements, and attribute selectors. Each row pairs the selector with a one-line example.

A selector picks the elements a rule applies to. Specificity decides which rule wins when several match: inline beats id, id beats class, class beats type. Read selectors right to left: the browser matches the rightmost part first, then walks up the combinators. The families below cover almost everything you will write.

Reference table · 53 entries
53 of 53 rows
Basic
Every element of that tag.button { }
Elements with that class..active { }
The single element with that id.#header { }
Every element.* { box-sizing: border-box; }
The document root; the usual place for global custom properties.:root { --gap: 1rem; }
Elements matched by A or B (grouping).h1, h2, h3 { }
Combinators
Any B descended from A.nav a { }
B that is a direct child of A.ul > li { }
B immediately after A, same parent.h1 + p { }
Every B that follows A, same parent.h1 ~ p { }
Pseudo-classes (state)
The element while the pointer is over it.a:hover { }
The element that has keyboard focus.input:focus { }
An element that is the first child of its parent.li:first-child { }
The nth child; takes formulas like 2n.tr:nth-child(2n) { }
Elements that do not match any inner selector; takes a list since Selectors 4.li:not(:first-child, .skip) { }
A checked checkbox, radio, or option.input:checked { }
A disabled input or button.button:disabled { }
A parent that contains a match for the inner selector.li:has(ul) { }
Any selector in the list; specificity is the highest in the list.:is(ol, ul) li { }
Same as :is(), but with zero specificity.:where(ol, ul) li { }
Focus that should show a ring, usually from the keyboard.a:focus-visible { }
An element that itself or a descendant has focus.form:focus-within { }
An element that is the last child of its parent.li:last-child { }
An element with no siblings.p:only-child { }
The nth sibling of the same tag; takes formulas like 2n.p:nth-of-type(2n) { }
The first or last sibling of the same tag.p:first-of-type { }
An element with no children and no text.td:empty { }
Unvisited links and already visited links.a:visited { }
Inputs marked required and inputs left optional.input:required { }
Inputs whose value passes or fails its validation rules.input:invalid { }
An input the user cannot edit.input:read-only { }
The element whose id matches the URL fragment.#note:target { }
The preselected option or default button of a group.input:default { }
A checkbox set to an indeterminate state by script.input:indeterminate { }
Any built-in element, or a custom element once it is registered.my-widget:defined { }
An element in the given language.p:lang(fr) { }
Pseudo-elements
A generated content node before the element.label::before { content: ""; }
A generated content node after the element.code::after { content: ";"; }
The first letter of a block of text.p::first-letter { }
The placeholder text of an input.input::placeholder { }
The first line of a block of text.p::first-line { }
The text the user has highlighted.::selection { }
The bullet or number of a list item.li::marker { }
The area behind a fullscreen element or dialog.dialog::backdrop { }
The browse button inside a file input.input::file-selector-button { }
A shadow-DOM part the host has exposed.my-widget::part(header) { }
Attribute selectors
Elements that have the attribute, any value.[required] { }
The attribute equals val exactly.[type="submit"] { }
The attribute starts with val.a[href^="https"] { }
The attribute ends with val.a[href$=".pdf"] { }
The attribute contains val.a[href*="login"] { }
A space-separated list that includes val.[class~="badge"] { }
The value equals val or starts with val plus a hyphen.[lang|="en"] { }