← Back to docs

CSS Selectors

JustHTML supports a comprehensive subset of CSS selectors for querying the DOM.

Basic Selectors

Selector Example Description
Tag div Elements by tag name
Class .intro Elements with class
ID #main Element with ID
Universal * All elements
doc.query("div")       # All <div> elements
doc.query(".intro")    # All elements with class="intro"
doc.query("#main")     # Element with id="main"
doc.query("*")         # All elements

Attribute Selectors

Selector Example Description
Has attribute [href] Elements with attribute
Exact match [type="text"] Exact attribute value
Starts with [href^="https"] Attribute starts with value
Ends with [href$=".pdf"] Attribute ends with value
Contains [href*="example"] Attribute contains value
Word match [class~="active"] Space-separated word match
Prefix match [lang\|="en"] Value or value followed by -
doc.query("[href]")              # All elements with href attribute
doc.query('[type="submit"]')     # Exact match
doc.query('[href^="https://"]')  # Links starting with https://
doc.query('[src$=".png"]')       # Images ending with .png
doc.query('[class*="btn"]')      # Classes containing "btn"

Combinators

Combinator Example Description
Descendant div p <p> anywhere inside <div>
Child div > p <p> direct child of <div>
Adjacent h1 + p <p> immediately after <h1>
Sibling h1 ~ p Any <p> sibling after <h1>
doc.query("div p")          # Paragraphs anywhere in a div
doc.query("ul > li")        # Direct list items
doc.query("h1 + p")         # First paragraph after h1
doc.query("h1 ~ p")         # All paragraphs after h1

Pseudo-classes

Structural

Selector Description
:first-child First child of parent
:last-child Last child of parent
:only-child Only child of parent
:nth-child(n) Nth child (1-indexed)
:nth-last-child(n) Nth child from end
:first-of-type First of its type in parent
:last-of-type Last of its type in parent
:only-of-type Only of its type in parent
:nth-of-type(n) Nth of its type
:nth-last-of-type(n) Nth of its type from end
doc.query("li:first-child")       # First list item
doc.query("li:last-child")        # Last list item
doc.query("li:nth-child(2)")      # Second list item
doc.query("li:nth-child(odd)")    # Odd list items (1st, 3rd, 5th...)
doc.query("li:nth-child(even)")   # Even list items (2nd, 4th, 6th...)
doc.query("li:nth-child(3n)")     # Every 3rd item
doc.query("li:nth-child(3n+1)")   # 1st, 4th, 7th... (formula: An+B)

Content

Selector Description
:empty Elements with no children
:root Document root element
:contains("text") Non-standard (jQuery-style): elements whose descendant text contains text
:comment Non-standard: comment nodes (#comment)
doc.query("p:empty")    # Empty paragraphs
doc.query(":root")      # The <html> element
doc.query(":comment")   # Comment nodes

Negation

Selector Description
:not(selector) Elements not matching selector
doc.query("div:not(.hidden)")     # Visible divs
doc.query("input:not([disabled])")  # Enabled inputs

Selector Groups

Combine multiple selectors with commas:

doc.query("h1, h2, h3")           # All headings
doc.query(".btn, [type='submit']") # Buttons and submit inputs

Compound Selectors

Chain selectors without spaces:

doc.query("div.container")        # <div class="container">
doc.query("input[type='text']")   # <input type="text">
doc.query("li.active:first-child") # First li with class active

Examples

# Navigation links
doc.query("nav a")

# Active menu item
doc.query("nav li.active > a")

# Form inputs except hidden
doc.query("form input:not([type='hidden'])")

# Alternating table rows
doc.query("tr:nth-child(even)")

# First paragraph in each container
doc.query("div > p:first-of-type")

# External links
doc.query('a[href^="http"]:not([href*="mysite.com"])')