CSS selectors guide
Types, classes, attributes, and specificity.
Build basic and attribute selectors, compare them across three HTML scenarios, and inspect every match and its specificity.
articlePreparing the scenario and its results…
Selects every <article> element in the scenario.
<section
id="component-catalog"
class="catalog"
aria-label="Catalog of guides and demos"
>
<article
id="featured-card"
class="card featured"
data-kind="guide"
data-tags="css selectors"
data-code="CSS-BASICS"
data-file="selectors.pdf"
data-note="learn-selector-specificity"
lang="es-MX"
>
<h3>CSS selectors guide</h3>
<p>Types, classes, attributes, and specificity.</p>
</article>
<article
class="card"
data-kind="demo"
data-tags="html semantics"
data-code="HTML-BASICS"
data-file="semantics.html"
data-note="semantic-markup"
lang="en-US"
>
<h3>Semantic HTML</h3>
<p>Accessible structures for web documents.</p>
</article>
<article
class="card"
data-kind="guide"
data-tags="css layout"
data-code="CSS-GRID"
data-file="grid.pdf"
data-note="layout-selector-reference"
lang="es-ES"
>
<h3>CSS Grid guide</h3>
<p>Modern layouts with rows and columns.</p>
</article>
</section>article {
outline: 3px solid #f97316;
outline-offset: 3px;
background-color: color-mix(in oklch, #f97316 16%, transparent);
}CSS selectors guide
Compare what each syntax selects, how it contributes to specificity, and which restrictions are worth remembering before using it.
Matching, specificity, and the cascade answer different questions. Keeping them separate avoids attributing effects to a selector that actually depend on declarations or rule order.
(ID, CLASS, TYPE)ID counts ID selectors, CLASS groups classes, attributes, and pseudo-classes, and TYPE counts types and pseudo-elements. They are compared from left to right.
selector → matchesThe selector decides which elements enter the rule. Origin, layers, importance, specificity, and order decide which declaration wins.
style="..."A style attribute participates in the cascade with its own priority, but it does not add a fourth column to a selector specificity tuple.
Select by type, class, or ID, or combine several conditions on the same element.
*Represents any element within the context where it is evaluated.
Specificity(0, 0, 0)*Matches: <section>
This text is not an element.
Matches: <span>Matches</span>
</section>.card *<article class="card">
Matches: <strong>Matches</strong>
Matches: <span>Matches</span>
</article>
<p>Does not match</p>ESelects every element with the given name, such as article.
Specificity(0, 0, 1)articleMatches: <article>Matches</article>
<section>Does not match</section>button<nav>
<a href="#">Does not match</a>
Matches: <button type="button">Matches</button>
</nav>.classSelects any element whose class list contains the given identifier.
Specificity(0, 1, 0).featuredMatches: <article class="featured">Matches</article>
Matches: <p class="featured">Matches</p>
<aside>Does not match</aside>.note<aside>
Matches: <p class="note">Matches</p>
<p>Does not match</p>
</aside>#idSelects elements whose identifier exactly matches the value written after #.
Specificity(1, 0, 0)#featured-cardMatches: <article id="featured-card">Matches</article>
<article id="secondary-card">Does not match</article>#primary-action<form>
Matches: <button id="primary-action">Matches</button>
<button>Does not match</button>
</form>E.class.classSelects one element that simultaneously satisfies every condition written without combinators.
Specificity(0, 2, 1)article.card.featuredMatches: <article class="card featured">Matches</article>
<article class="card">Does not match</article>button.action.primary<form>
Matches: <button class="action primary">Matches</button>
<a class="action primary">Does not match</a>
<button class="action">Does not match</button>
</form>Distinguish between checking that an attribute exists and requiring its complete value to equal a particular string.
[attr]Selects elements that have the given attribute, whatever its value is.
Specificity(0, 1, 0)[data-kind]Matches: <article data-kind="">Matches</article>
<article>Does not match</article>[disabled]<form>
Matches: <input disabled value="Matches">
<input value="Does not match">
</form>[attr="value"]Selects elements whose complete attribute value is exactly the given string.
Specificity(0, 1, 0)[data-kind="guide"]Matches: <article data-kind="guide">Matches</article>
<article data-kind="guide-draft">Does not match</article>[data-state="open"]<dialog>
Matches: <button data-state="open">Matches</button>
<button data-state="opening">Does not match</button>
</dialog>Each operator interprets the attribute value differently: word, hyphenated prefix, beginning, ending, or substring.
[attr~="word"]Finds a complete word in a list of values separated by CSS whitespace.
Specificity(0, 1, 0)[data-tags~="css"]Matches: <article data-tags="css selectors">Matches</article>
<article data-tags="scss">Does not match</article>[rel~="external"]<nav>
Matches: <a rel="help external">Matches</a>
<a rel="external-link">Does not match</a>
</nav>[attr|="prefix"]Matches the exact value or that value immediately followed by a hyphen.
Specificity(0, 1, 0)[lang|="es"]Matches: <article lang="es">Matches</article>
Matches: <article lang="es-MX">Matches</article>
<article lang="especial">Does not match</article>[data-locale|="pt"]<section>
Matches: <p data-locale="pt-BR">Matches</p>
<p data-locale="pt_BR">Does not match</p>
</section>[attr^="prefix"]Selects attribute values that begin exactly with the given string.
Specificity(0, 1, 0)[data-code^="CSS"]Matches: <article data-code="CSS-GRID">Matches</article>
<article data-code="HTML-CSS">Does not match</article>[href^="https://"] <nav>
Matches: <a href="https://example.com" >Matches</a>
<a href="/docs/css">Does not match</a>
</nav>[attr$="suffix"]Selects attribute values that end exactly with the given string.
Specificity(0, 1, 0)[data-file$=".pdf"]Matches: <a data-file="selectors.pdf">Matches</a>
<a data-file="selectors.html">Does not match</a>[href$=".pdf"]<ul>
<li>
Matches: <a href="/guide.pdf">Matches</a>
</li>
<li>
<a href="/pdf/guide">Does not match</a>
</li>
</ul>[attr*="fragment"]Selects values containing at least one occurrence of the given string.
Specificity(0, 1, 0)[data-note*="selector"]Matches: <article data-note="selector-reference">Matches</article>
<article data-note="layout-reference">Does not match</article>[href*="/docs/"]<nav>
Matches: <a href="/docs/selectors/">Matches</a>
<a href="/documentation/">Does not match</a>
</nav>The i and s modifiers change how the value is compared regardless of the document language default.
[attr="value" i]Compares the attribute value without letter-case distinctions in the ASCII range.
Specificity(0, 1, 0)[data-code="css-basics" i]Matches: <article data-code="CSS-BASICS">Matches</article>
Matches: <article data-code="Css-Basics">Matches</article>
<article data-code="HTML-BASICS">Does not match</article>[data-theme="dark" i]<section>
Matches: <button data-theme="DARK">Matches</button>
<button data-theme="light">Does not match</button>
</section>This Baseline status belongs to the i modifier. The preview separately checks whether the current browser can evaluate the concrete selector.
[attr="value" s]Forces an identical value comparison that preserves letter case.
Specificity(0, 1, 0)[data-code="CSS-BASICS" s]Matches: <article data-code="CSS-BASICS">Matches</article>
<article data-code="css-basics">Does not match</article>[data-state="OPEN" s]<dialog>
Matches: <button data-state="OPEN">Matches</button>
<button data-state="open">Does not match</button>
</dialog>This Baseline status belongs to the s modifier. If the browser does not support it, the lab reports it as not evaluable instead of simulating a match.