CSS Selectors

All selector types with descriptions, examples, and specificity values.

basic4 selectors
*
Universal selector — matches any element.
* { box-sizing: border-box; }
specificity: 0,0,0
element
Type selector — matches all elements of the given tag name.
p { margin: 0; }
specificity: 0,0,1
.class
Class selector — matches elements with the specified class attribute.
.card { padding: 16px; }
specificity: 0,1,0
#id
ID selector — matches the element with the given id attribute. IDs must be unique per page.
#header { position: sticky; }
specificity: 1,0,0
attribute7 selectors
[attr]
Presence — matches elements that have the attribute, regardless of value.
a[href] { color: blue; }
specificity: 0,1,0
[attr=val]
Exact match — matches elements where the attribute equals the exact value.
input[type="text"]
specificity: 0,1,0
[attr~=val]
Word match — matches elements where the attribute contains val as a space-separated word.
[class~="active"]
specificity: 0,1,0
[attr|=val]
Hyphen match — matches val or val followed by a hyphen. Designed for language codes like lang|=en.
[lang|="en"]
specificity: 0,1,0
[attr^=val]
Prefix match — matches elements where the attribute value starts with val.
a[href^="https"]
specificity: 0,1,0
[attr$=val]
Suffix match — matches elements where the attribute value ends with val.
a[href$=".pdf"]
specificity: 0,1,0
[attr*=val]
Substring match — matches elements where the attribute value contains val anywhere.
[class*="icon"]
specificity: 0,1,0
pseudo-class16 selectors
:hover
Matches when the user's pointer is over the element.
a:hover { text-decoration: underline; }
specificity: +0,1,0
:focus
Matches when the element has keyboard focus.
input:focus { outline: 2px solid blue; }
specificity: +0,1,0
:active
Matches while the element is being activated (e.g., during a click).
button:active { transform: scale(0.98); }
specificity: +0,1,0
:visited
Matches anchor elements that have been visited. Styling is restricted to prevent history sniffing.
a:visited { color: purple; }
specificity: +0,1,0
:first-child
Matches an element that is the first child of its parent.
li:first-child { font-weight: bold; }
specificity: +0,1,0
:last-child
Matches an element that is the last child of its parent.
li:last-child { border-bottom: none; }
specificity: +0,1,0
:nth-child(n)
Matches elements based on their position. Accepts keywords (odd, even) or formulas (2n+1).
tr:nth-child(even) { background: #f5f5f5; }
specificity: +0,1,0
:nth-of-type(n)
Like :nth-child but only counts siblings of the same element type.
p:nth-of-type(2) { color: gray; }
specificity: +0,1,0
:not(selector)
Negation — matches elements that do not match the argument selector.
input:not([type='submit'])
specificity: +specificity of argument
:is(sel, ...)
Matches any element that matches one of the selectors in the list. Forgiving — ignores invalid selectors.
:is(h1, h2, h3) { font-weight: bold; }
specificity: +highest specificity in list
:where(sel, ...)
Like :is() but contributes zero specificity — useful for low-priority base styles.
:where(ul, ol) { padding-left: 1.5em; }
specificity: 0,0,0
:has(selector)
Relational pseudo-class — matches elements that contain a descendant matching the argument. ('parent selector')
div:has(img) { display: grid; }
specificity: +specificity of argument
:checked
Matches checkboxes, radio buttons, and options that are currently selected.
input:checked + label { color: green; }
specificity: +0,1,0
:disabled
Matches form elements that are disabled.
button:disabled { opacity: 0.5; }
specificity: +0,1,0
:empty
Matches elements that have no children (no text nodes either).
p:empty { display: none; }
specificity: +0,1,0
:root
Matches the document root element — in HTML, this is <html>. Higher specificity than html selector.
:root { --spacing: 8px; }
specificity: 0,1,0
pseudo-element7 selectors
::before
Creates a pseudo-element as the first child of the selected element. Requires content property.
.icon::before { content: "▶"; }
specificity: +0,0,1
::after
Creates a pseudo-element as the last child of the selected element. Requires content property.
a::after { content: " ↗"; }
specificity: +0,0,1
::first-line
Matches the first rendered line of a block element. Only certain properties apply.
p::first-line { font-variant: small-caps; }
specificity: +0,0,1
::first-letter
Matches the first letter (or character) of a block element. Used for drop cap effects.
p::first-letter { font-size: 3em; float: left; }
specificity: +0,0,1
::placeholder
Matches the placeholder text of an input or textarea.
input::placeholder { color: #aaa; }
specificity: +0,0,1
::selection
Matches the portion of text selected by the user.
::selection { background: #ff0; color: #000; }
specificity: +0,0,0
::marker
Matches the marker box of a list item (bullet or number).
li::marker { color: var(--accent); }
specificity: +0,0,1
combinators5 selectors
A B
Descendant combinator — matches B that is anywhere inside A (not just direct children).
nav a { color: white; }
specificity: sum of A and B
A > B
Child combinator — matches B that is a direct child of A only.
ul > li { list-style: disc; }
specificity: sum of A and B
A + B
Adjacent sibling combinator — matches B that immediately follows A (same parent).
h2 + p { margin-top: 0; }
specificity: sum of A and B
A ~ B
General sibling combinator — matches all B elements that follow A (same parent, not just adjacent).
h2 ~ p { color: gray; }
specificity: sum of A and B
A, B
Selector list — matches both A and B. A comma-separated list of selectors sharing the same rules.
h1, h2, h3 { line-height: 1.2; }
specificity: each evaluated separately