Skip to main content

CSS DOM Selectors

Basic Selectors

Element Selector

// Select all <p> elements
document.getElementsByTagName('p');
document.querySelectorAll('p');
p { /* styles */ }

Class Selector

// Select elements with class="highlight"
document.getElementsByClassName('highlight');
document.querySelectorAll('.highlight');
.highlight { /* styles */ }

ID Selector

// Select element with id="header"
document.getElementById('header');
document.querySelector('#header');
#header { /* styles */ }

Combination Selectors

Descendant Selector

// Select all <p> elements inside <div>
document.querySelectorAll('div p');
div p { /* styles */ }

Child Selector

// Select all direct <p> children of <div>
document.querySelectorAll('div > p');
div > p { /* styles */ }

Adjacent Sibling

// Select <p> immediately after <h2>
document.querySelectorAll('h2 + p');
h2 + p { /* styles */ }

General Sibling

// Select all <p> elements that follow <h2>
document.querySelectorAll('h2 ~ p');
h2 ~ p { /* styles */ }

Attribute Selectors

Has Attribute

// Select elements with 'data-type' attribute
document.querySelectorAll('[data-type]');
[data-type] { /* styles */ }

Exact Attribute Value

// Select elements with type="text"
document.querySelectorAll('[type="text"]');
[type="text"] { /* styles */ }

Contains Word

// Select elements with class containing "btn"
document.querySelectorAll('[class~="btn"]');
[class~="btn"] { /* styles */ }

Starts With

// Select elements with href starting with "https"
document.querySelectorAll('[href^="https"]');
[href^="https"] { /* styles */ }

Ends With

// Select elements with src ending in ".pdf"
document.querySelectorAll('[src$=".pdf"]');
[src$=".pdf"] { /* styles */ }

Contains Substring

// Select elements with href containing "example"
document.querySelectorAll('[href*="example"]');
[href*="example"] { /* styles */ }

Pseudo-classes

State Pseudo-classes

// Select all checked inputs
document.querySelectorAll('input:checked');
input:checked { /* styles */ }

Position Pseudo-classes

// Select first paragraph
document.querySelector('p:first-child');
// Select last paragraph
document.querySelector('p:last-child');
// Select specific numbered element
document.querySelector('p:nth-child(2)');
p:first-child { /* styles */ }
p:last-child { /* styles */ }
p:nth-child(2) { /* styles */ }

Pattern Pseudo-classes

// Select even paragraphs
document.querySelectorAll('p:nth-child(even)');
// Select odd paragraphs
document.querySelectorAll('p:nth-child(odd)');
p:nth-child(even) { /* styles */ }
p:nth-child(odd) { /* styles */ }

Multiple Selectors

// Select multiple elements
document.querySelectorAll('h1, .highlight, #header');
h1, .highlight, #header { /* styles */ }

CSS Advanced Selectors: :has, :not, :is, :where

These powerful CSS pseudo-class selectors help simplify styling logic and improve maintainability.


:has() – Parent Selector (CSS Relational Selector)

💡 Selects an element that contains a specific child element.

✅ Example: Style a <div> that has an <img> inside

div:has(img) {
border: 2px solid blue;
}

📌 Effect:

  • Adds a blue border only to <div> elements that contain an <img>.

🚀 More Examples:

/* Highlight a <label> if its <input> is checked */
label:has(input:checked) {
color: green;
font-weight: bold;
}

/* Style a card only if it has a button */
.card:has(button) {
background-color: lightgray;
}

:not() – Exclude Elements

💡 Selects elements that do NOT match a certain selector.

✅ Example: Select all <button> elements except those with .disabled

button:not(.disabled) {
background-color: blue;
color: white;
}

📌 Effect:

  • All enabled buttons get blue styling, but .disabled buttons stay unchanged.

🚀 More Examples:

/* Select all list items except the first one */
li:not(:first-child) {
margin-left: 10px;
}

/* Select all paragraphs except those inside a .container */
p:not(.container p) {
font-size: 16px;
}

:is() – Grouping Selectors (Better Readability & Performance)

💡 Simplifies multiple selectors into one.

✅ Example: Apply same styles to <h1>, <h2>, and <h3>

:is(h1, h2, h3) {
color: red;
}

📌 Effect:

  • All <h1>, <h2>, and <h3> elements will be red.

🚀 More Examples:

/* Apply padding to all input types except checkbox & radio */
:is(input, textarea):not([type="checkbox"], [type="radio"]) {
padding: 10px;
}

/* Style links differently inside nav */
nav :is(a, button) {
color: white;
font-weight: bold;
}

:where() – Works Like :is(), But Lower Specificity

💡 Same as :is(), but without affecting specificity.
Best for utility classes & overrides.

✅ Example: Style multiple elements without increasing specificity

:where(h1, h2, h3) {
margin: 0;
padding: 0;
}

📌 Effect:

  • Works like :is(), but allows easier overriding later.

🚀 More Examples:

/* Form input styling with low specificity */
:where(input, select, textarea) {
font-size: 16px;
border-radius: 5px;
}

/* Navigation links with low specificity */
nav :where(a, button) {
text-decoration: none;
}

🔥 Summary Table

SelectorPurposeExample
:has()Selects parent if it contains a specific childdiv:has(img) {}
:not()Excludes elements from selectionbutton:not(.disabled) {}
:is()Groups multiple selectors (affects specificity):is(h1, h2, h3) {}
:where()Groups selectors (low specificity):where(input, textarea) {}

🚀 Best Practices

✔ Use :has() for parent-child relationships (currently limited browser support).
✔ Use :not() to exclude elements from styling.
✔ Use :is() for cleaner selector grouping.
✔ Use :where() for utility styles with low specificity.

Browser Support

  • :not(), :is(), :where()Widely supported
  • ⚠️ :has()Supported in modern browsers (Chrome, Edge, Safari 15+), but not in Firefox (yet)

Best Practices

  1. Use querySelector/querySelectorAll for modern applications

    • More flexible and powerful than older methods
    • Supports all CSS selector syntax
    • Returns static NodeList (won't auto-update)
  2. Performance Considerations

    • ID selectors are fastest (#id)
    • Class selectors are next fastest (.class)
    • Complex selectors are slowest (div > p:nth-child(2))
  3. Specificity Order (most to least specific)

    • ID selectors (#id)
    • Class selectors (.class)
    • Element selectors (p)
  4. Modern Usage Tips

    • Prefer querySelector over getElementById for consistency
    • Use closest() for finding parent elements
    • Use matches() to test if element matches selector
    element.closest('.container');
    element.matches('.active');