CSS selector tester
Paste HTML and one or more selectors (one per line) and see exactly which elements each selector matches: the elements highlighted in the parsed tree with their path and line, the count per selector, and its specificity counted per section 15 of Selectors Level 4. The HTML is parsed inertly with the same parser as the HTML structure explainer; the selectors are parsed and matched by Selectors Level 4's own rules (compound by compound, right to left), including :is(), :not(), :where(), :has(), :nth-child(An+B of S), attribute operators with the i and s flags, CSS escapes and the form-state pseudo-classes read from attributes. Invalid selectors are named with the position of the error; the pseudo-classes a static document cannot answer are marked. Checked against Chromium's querySelectorAll.
Web & HTTP20 elements, 19 selectors. 19 valid, none invalid; 14 elements matched by at least one selector.
The selectors
| # | selector | matches | A,B,C | notes |
|---|---|---|---|---|
li | 3 matches | 0,0,1 | ||
li.item | 3 matches | 0,1,1 | ||
.item.first | one match | 0,2,0 | ||
#top | one match | 1,0,0 | ||
nav > ul > li:first-child | one match | 0,1,3 | ||
li:last-child a | one match | 0,1,2 | ||
li:nth-child(2) | one match | 0,1,1 | ||
li:nth-child(odd) | 2 matches | 0,1,1 | ||
a[href] | 2 matches | 0,1,1 | ||
a:any-link | 2 matches | 0,1,1 | :any-link is read from attributes the way the HTML Standard defines it (checked, selected, disabled including a disabled fieldset's descendants outside its first legend, required, readonly, open, href on a or area, lang, dir, a hyphen in a custom element's name): a browser's answer can differ where scripts or user actions changed the state. | |
a[target=_blank] | one match | 0,1,1 | ||
a[href^="/d"] | one match | 0,1,1 | ||
[data-x~=b] | one match | 0,1,0 | ||
[title="hello world" i] | one match | 0,1,0 | ||
[title="hello world"] | no match | 0,1,0 | ||
h1 + p | one match | 0,0,2 | ||
h1 ~ p | 4 matches | 0,0,2 | ||
main * | 7 matches | 0,0,1 | ||
P.LEAD | no match | 0,1,1 |
A selector that names a pseudo-element (::before, ::first-line, …) selects a box, not an element; querySelectorAll returns nothing for it, and the count shown is of the elements that would originate the pseudo-element. The specificity is the triple of the most specific member of the list, counted per Selectors 4 section 15 from the parsed selector, so a member that a forgiving :is() or :where() dropped counts zero (16.1); the specificity calculator counts the text as written. Click a number to highlight one selector's matches in the tree.
The matched elements
- 1
li3 matcheshtml > body > nav > ul > li:nth-child(1)line 7html > body > nav > ul > li:nth-child(2)line 8html > body > nav > ul > li:nth-child(3)line 9
- 2
li.item3 matcheshtml > body > nav > ul > li:nth-child(1)line 7html > body > nav > ul > li:nth-child(2)line 8html > body > nav > ul > li:nth-child(3)line 9
- 3
.item.firstone matchhtml > body > nav > ul > li:nth-child(1)line 7
- 4
#topone matchhtml > body > navline 5
- 5
nav > ul > li:first-childone matchhtml > body > nav > ul > li:nth-child(1)line 7
- 6
li:last-child aone matchhtml > body > nav > ul > li:nth-child(3) > aline 9 “No href”
- 7
li:nth-child(2)one matchhtml > body > nav > ul > li:nth-child(2)line 8
- 8
li:nth-child(odd)2 matcheshtml > body > nav > ul > li:nth-child(1)line 7html > body > nav > ul > li:nth-child(3)line 9
- 9
a[href]2 matcheshtml > body > nav > ul > li:nth-child(1) > aline 7 “Home”html > body > nav > ul > li:nth-child(2) > aline 8 “Docs”
- 10
a:any-link2 matcheshtml > body > nav > ul > li:nth-child(1) > aline 7 “Home”html > body > nav > ul > li:nth-child(2) > aline 8 “Docs”
- 11
a[target=_blank]one matchhtml > body > nav > ul > li:nth-child(2) > aline 8 “Docs”
- 12
a[href^="/d"]one matchhtml > body > nav > ul > li:nth-child(2) > aline 8 “Docs”
- 13
[data-x~=b]one matchhtml > body > main > divline 18
- 14
[title="hello world" i]one matchhtml > body > main > divline 18
- 16
h1 + pone matchhtml > body > main > p:nth-child(2)line 14 “Lead .”
- 17
h1 ~ p4 matcheshtml > body > main > p:nth-child(2)line 14 “Lead .”html > body > main > p:nth-child(3)line 15html > body > main > p:nth-child(4)line 16html > body > main > p:nth-child(5)line 17
- 18
main *7 matcheshtml > body > main > h1line 13 “Title”html > body > main > p:nth-child(2)line 14 “Lead .”html > body > main > p:nth-child(2) > emline 14 “text”html > body > main > p:nth-child(3)line 15html > body > main > p:nth-child(4)line 16html > body > main > p:nth-child(5)line 17html > body > main > divline 18
The parsed tree
Every element of the document the parser built, with the numbers of the selectors that match it. A dot in the gutter marks an element the parser created (html, head, body, tbody).
- 2
<html lang="en"> - 3
<head> - 3
<title>“Menu” - 4
<body> - 5
<nav id="top" class="menu main">4 - 6
<ul> - 7
<li class="item first">12358 - 7
<a href="/">“Home”910 - 8
<li class="item">127 - 8
<a href="/docs" target="_blank">“Docs”9101112 - 9
<li class="item last">128 - 9
<a>“No href”6 - 12
<main> - 13
<h1>“Title”18 - 14
<p class="lead">“Lead .”161718 - 14
<em>“text”18 - 15
<p>1718 - 16
<p>1718 - 17
<p>1718 - 18
<div data-x="A b" title="Hello World">131418
The same tree, with the parser's repairs and errors, is in the HTML structure & DOM explainer, and each selector's counting in the CSS specificity calculator. The tester reads a static tree: no stylesheet is applied, no script runs, nothing is focused or hovered, nothing was visited, and :scope is the document root. :empty follows Chromium (Level 3) where Selectors Level 4 has moved on; the s flag and the quoted :lang() form follow Level 4 where Chromium has not (checked 2026-10-05). A selector left open at the end is closed there, as CSS Syntax does. Class and id match case-sensitively in every mode (the Quirks Mode Standard no longer defines a case quirk for them). Inputs over 200.000 characters of HTML are refused.
Referenzen
- Selectors Level 4, W3C Working Draft 22 January 2026
- CSS Syntax Module Level 3, W3C Candidate Recommendation Draft 1 October 2026
- HTML Living Standard (WHATWG): Case-sensitivity of selectors; the pseudo-classes :enabled, :disabled, :checked, :required, :optional, :read-write, :open, :defined, :link
- Quirks Mode Standard (WHATWG), Living Standard, last updated 30 September 2026
- parse5 8.0.1, the HTML parser (MIT)