CSS Selectors Cheat Sheet

Complete reference guide for all CSS selector types with examples and browser support

Table of Contents

Basic Selectors

* (Universal Selector)

Selects all elements in the document.

/* Resets margin and padding for all elements */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
All Browsers

element (Type Selector)

Selects all elements of the specified type.

/* Styles all paragraph elements */
p {
    font-size: 16px;
    line-height: 1.6;
}

/* Styles all h1 headings */
h1 {
    color: #333;
    font-size: 2em;
}
All Browsers

.class (Class Selector)

Selects all elements with the specified class attribute.

/* Selects elements with class="button" */
.button {
    padding: 10px 20px;
    background: #007bff;
    color: white;
}

/* Multiple classes */
.button.primary {
    background: #28a745;
}
All Browsers

#id (ID Selector)

Selects the element with the specified id attribute. IDs should be unique per page.

/* Selects element with id="header" */
#header {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 1000;
}
All Browsers

[attribute] (Attribute Selector)

Selects elements that have the specified attribute, regardless of its value.

/* Selects all elements with a title attribute */
[title] {
    cursor: help;
    border-bottom: 1px dotted;
}

/* Selects all inputs with a required attribute */
input[required] {
    border-color: red;
}
All Browsers

Combinator Selectors

A B (Descendant Selector)

Selects all B elements that are descendants of A (at any level).

/* Selects all 

inside

, at any depth */ div p { color: blue; } /* Selects all inside elements with class="container" */ .container span { font-weight: bold; }
All Browsers

A > B (Child Selector)

Selects all B elements that are direct children of A.

/* Selects only direct 
  • children of
      */ ul > li { list-style: square; } /* Does not select nested
    • elements */ .menu > li { display: inline-block; }
  • All Browsers

    A + B (Adjacent Sibling Selector)

    Selects the first B element that immediately follows A, where both share the same parent.

    /* Selects the first 

    immediately after

    */ h2 + p { font-size: 1.2em; margin-top: 0; } /* Selects label immediately after checked input */ input:checked + label { color: green; }

    All Browsers

    A ~ B (General Sibling Selector)

    Selects all B elements that follow A (not necessarily immediately), where both share the same parent.

    /* Selects all 

    elements that follow

    */ h2 ~ p { color: gray; } /* Selects all sibling divs after .intro */ .intro ~ div { margin-top: 20px; }

    All Browsers

    Attribute Selectors

    [attr="value"]

    Selects elements with an attribute exactly equal to the specified value.

    /* Selects inputs with type="text" */
    input[type="text"] {
        border: 1px solid #ccc;
    }
    
    /* Selects links with specific target */
    a[target="_blank"] {
        padding-right: 15px;
    }
    All Browsers

    [attr~="value"]

    Selects elements with an attribute containing the word value (space-separated).

    /* Selects elements with class attribute containing "button" */
    [class~="button"] {
        cursor: pointer;
    }
    
    /* HTML: 
    */
    All Browsers

    [attr|="value"]

    Selects elements with an attribute starting with value followed by a hyphen, or exactly equal to value.

    /* Selects elements with lang attribute starting with "en" */
    [lang|="en"] {
        quotes: '"' '"';
    }
    
    /* Matches: lang="en", lang="en-US", lang="en-GB" */
    All Browsers

    [attr^="value"]

    Selects elements with an attribute starting with the specified value.

    /* Selects links starting with "https" */
    a[href^="https"] {
        padding-left: 20px;
    }
    
    /* Selects elements with class starting with "icon-" */
    [class^="icon-"] {
        display: inline-block;
        width: 16px;
        height: 16px;
    }
    All Browsers

    [attr$="value"]

    Selects elements with an attribute ending with the specified value.

    /* Selects links to PDF files */
    a[href$=".pdf"] {
        background: url(pdf-icon.png) no-repeat right;
    }
    
    /* Selects images with .jpg extension */
    img[src$=".jpg"] {
        border: 2px solid gold;
    }
    All Browsers

    [attr*="value"]

    Selects elements with an attribute containing the specified value anywhere.

    /* Selects links containing "google" in href */
    a[href*="google"] {
        color: #4285f4;
    }
    
    /* Selects elements with class containing "btn" */
    [class*="btn"] {
        padding: 8px 16px;
    }
    All Browsers

    Pseudo-classes

    User Action Pseudo-classes

    :hover

    Selects elements when the user hovers over them with a pointer.

    /* Change color on hover */
    a:hover {
        color: red;
        text-decoration: underline;
    }
    
    button:hover {
        background: #0056b3;
        transform: scale(1.05);
    }
    All Browsers

    :focus

    Selects an element when it has focus (keyboard or mouse interaction).

    /* Highlight focused input */
    input:focus {
        border-color: #007bff;
        outline: 2px solid #007bff;
        outline-offset: 2px;
    }
    All Browsers

    :active

    Selects an element during the time it is being activated (clicked).

    /* Style while clicking */
    button:active {
        transform: scale(0.95);
        background: #003d82;
    }
    All Browsers

    :visited

    Selects links that have been visited by the user.

    /* Style visited links */
    a:visited {
        color: purple;
    }
    All Browsers (Limited properties for privacy)

    :focus-within

    Selects an element if it or any of its descendants have focus.

    /* Highlight form when any input is focused */
    form:focus-within {
        box-shadow: 0 0 10px rgba(0, 123, 255, 0.5);
    }
    
    .search-box:focus-within {
        border-color: #007bff;
    }
    Modern Browsers (Chrome 60+, Firefox 52+, Safari 10.1+)

    :focus-visible

    Selects an element that has focus and the browser determines focus should be visible (typically keyboard navigation).

    /* Show outline only for keyboard navigation */
    button:focus-visible {
        outline: 2px solid #007bff;
        outline-offset: 2px;
    }
    
    /* Hide default focus for mouse clicks */
    button:focus:not(:focus-visible) {
        outline: none;
    }
    Modern Browsers (Chrome 86+, Firefox 85+, Safari 15.4+)

    Structural Pseudo-classes

    :first-child

    Selects an element that is the first child of its parent.

    /* Style first list item */
    li:first-child {
        font-weight: bold;
    }
    
    p:first-child {
        margin-top: 0;
    }
    All Browsers

    :last-child

    Selects an element that is the last child of its parent.

    /* Remove margin from last paragraph */
    p:last-child {
        margin-bottom: 0;
    }
    
    .menu li:last-child {
        border-right: none;
    }
    All Browsers

    :nth-child(n)

    Selects elements based on their position among siblings. Accepts numbers, keywords (odd, even), or formulas (an+b).

    /* Select every odd row */
    tr:nth-child(odd) {
        background: #f5f5f5;
    }
    
    /* Select every 3rd element */
    li:nth-child(3n) {
        color: red;
    }
    
    /* Select first 3 elements */
    div:nth-child(-n+3) {
        font-weight: bold;
    }
    
    /* Select element at position 5 */
    p:nth-child(5) {
        color: blue;
    }
    All Browsers

    :nth-last-child(n)

    Like :nth-child(), but counts from the last child backwards.

    /* Select last 2 elements */
    li:nth-last-child(-n+2) {
        font-style: italic;
    }
    
    /* Select second from last */
    div:nth-last-child(2) {
        border-bottom: 2px solid blue;
    }
    All Browsers

    :nth-of-type(n)

    Selects elements based on their position among siblings of the same type.

    /* Select every 2nd paragraph (ignoring other elements) */
    p:nth-of-type(2n) {
        color: gray;
    }
    
    /* Select first h2 heading */
    h2:nth-of-type(1) {
        color: red;
    }
    All Browsers

    :nth-last-of-type(n)

    Like :nth-of-type(), but counts from the last element of that type backwards.

    /* Select last 3 paragraphs */
    p:nth-last-of-type(-n+3) {
        background: lightyellow;
    }
    All Browsers

    :first-of-type

    Selects the first element of its type among siblings.

    /* Style first paragraph in each section */
    section p:first-of-type {
        font-size: 1.2em;
    }
    All Browsers

    :last-of-type

    Selects the last element of its type among siblings.

    /* Remove margin from last paragraph */
    article p:last-of-type {
        margin-bottom: 0;
    }
    All Browsers

    :only-child

    Selects an element if it is the only child of its parent.

    /* Style only if it's the sole child */
    li:only-child {
        list-style: none;
    }
    
    p:only-child {
        text-align: center;
    }
    All Browsers

    :only-of-type

    Selects an element if it is the only element of its type among siblings.

    /* Style if only one paragraph exists */
    p:only-of-type {
        color: blue;
    }
    All Browsers

    :empty

    Selects elements that have no children (including text nodes).

    /* Hide empty elements */
    div:empty {
        display: none;
    }
    
    /* Add placeholder for empty cells */
    td:empty::before {
        content: "—";
        color: #999;
    }
    All Browsers

    Form Pseudo-classes

    :checked

    Selects radio buttons, checkboxes, or option elements that are checked or selected.

    /* Style checked checkbox */
    input[type="checkbox"]:checked {
        accent-color: green;
    }
    
    /* Custom checkbox using :checked + label */
    input:checked + label {
        color: green;
        font-weight: bold;
    }
    All Browsers

    :disabled

    Selects form elements that are disabled.

    /* Style disabled inputs */
    input:disabled {
        background: #f0f0f0;
        cursor: not-allowed;
        opacity: 0.6;
    }
    All Browsers

    :enabled

    Selects form elements that are enabled (not disabled).

    /* Style enabled inputs */
    input:enabled {
        border: 1px solid #ccc;
    }
    All Browsers

    :required

    Selects form elements with the required attribute.

    /* Highlight required fields */
    input:required {
        border-left: 3px solid red;
    }
    
    /* Add asterisk to required field labels */
    label:has(+ input:required)::after {
        content: " *";
        color: red;
    }
    All Browsers

    :optional

    Selects form elements without the required attribute.

    /* Style optional fields differently */
    input:optional {
        border-left: 3px solid gray;
    }
    All Browsers

    :valid

    Selects form elements whose value validates according to their type and constraints.

    /* Green border for valid input */
    input:valid {
        border-color: green;
    }
    
    /* Show checkmark for valid email */
    input[type="email"]:valid {
        background: url(checkmark.svg) no-repeat right center;
    }
    All Browsers

    :invalid

    Selects form elements whose value does not validate.

    /* Red border for invalid input */
    input:invalid {
        border-color: red;
    }
    
    /* Show error icon */
    input:invalid:not(:placeholder-shown) {
        background: url(error.svg) no-repeat right center;
    }
    All Browsers

    :placeholder-shown

    Selects input or textarea elements that are currently showing placeholder text.

    /* Style when placeholder is visible */
    input:placeholder-shown {
        border-color: #ccc;
    }
    
    /* Validate only when user has entered something */
    input:not(:placeholder-shown):invalid {
        border-color: red;
    }
    Modern Browsers (Chrome 47+, Firefox 51+, Safari 9+)

    Other Pseudo-classes

    :root

    Selects the root element of the document (html element in HTML). Often used for CSS custom properties.

    /* Define global CSS variables */
    :root {
        --primary-color: #007bff;
        --secondary-color: #6c757d;
        --font-size: 16px;
    }
    
    /* Use variables */
    button {
        background: var(--primary-color);
        font-size: var(--font-size);
    }
    All Browsers

    :target

    Selects the element whose id matches the URL fragment (anchor).

    /* Highlight section when linked via #section-id */
    :target {
        background: yellow;
        animation: highlight 2s;
    }
    
    /* Style targeted heading */
    h2:target {
        color: red;
        border-left: 4px solid red;
    }
    All Browsers

    :not(selector)

    Selects elements that do not match the given selector.

    /* Select all inputs except submit buttons */
    input:not([type="submit"]) {
        border: 1px solid #ccc;
    }
    
    /* Select all paragraphs except first */
    p:not(:first-child) {
        margin-top: 1em;
    }
    
    /* Multiple selectors in :not() */
    button:not(.primary):not(.secondary) {
        background: gray;
    }
    All Browsers (Level 3), Modern Browsers for complex selectors

    Pseudo-elements

    Note: Pseudo-elements use double colon (::) notation to distinguish them from pseudo-classes. Single colon (:) syntax is supported for backwards compatibility for ::before, ::after, ::first-line, and ::first-letter.

    ::before

    Creates a pseudo-element that is the first child of the selected element. Often used for decorative content.

    /* Add icon before links */
    a::before {
        content: "🔗 ";
    }
    
    /* Add opening quote */
    blockquote::before {
        content: open-quote;
        font-size: 2em;
        color: #999;
    }
    
    /* Decorative element */
    .button::before {
        content: "";
        display: inline-block;
        width: 10px;
        height: 10px;
        background: white;
        margin-right: 5px;
    }
    All Browsers

    ::after

    Creates a pseudo-element that is the last child of the selected element.

    /* Add arrow after links */
    a[target="_blank"]::after {
        content: " ↗";
    }
    
    /* Clearfix */
    .clearfix::after {
        content: "";
        display: table;
        clear: both;
    }
    
    /* Add required indicator */
    .required::after {
        content: " *";
        color: red;
    }
    All Browsers

    ::first-line

    Selects the first line of a block-level element.

    /* Style first line of paragraphs */
    p::first-line {
        font-weight: bold;
        font-size: 1.2em;
        color: #333;
    }
    
    article::first-line {
        text-transform: uppercase;
    }
    All Browsers (Limited properties: font, color, background, text-decoration, etc.)

    ::first-letter

    Selects the first letter of a block-level element.

    /* Drop cap effect */
    p::first-letter {
        font-size: 3em;
        font-weight: bold;
        float: left;
        line-height: 1;
        margin-right: 5px;
        color: #e94560;
    }
    
    .intro::first-letter {
        background: #007bff;
        color: white;
        padding: 5px;
    }
    All Browsers (Limited properties: font, color, background, margin, padding, border, text-decoration, etc.)

    ::selection

    Selects the portion of an element that is selected by the user.

    /* Custom text selection color */
    ::selection {
        background: #007bff;
        color: white;
    }
    
    /* Firefox requires vendor prefix */
    ::-moz-selection {
        background: #007bff;
        color: white;
    }
    
    p::selection {
        background: yellow;
        color: black;
    }
    All Browsers (Firefox uses ::-moz-selection)

    ::placeholder

    Selects the placeholder text in input or textarea elements.

    /* Style placeholder text */
    input::placeholder {
        color: #999;
        font-style: italic;
        opacity: 1;
    }
    
    textarea::placeholder {
        color: #aaa;
        font-size: 0.9em;
    }
    All Modern Browsers

    ::marker

    Selects the marker box of a list item (bullet or number).

    /* Style list markers */
    li::marker {
        color: #e94560;
        font-size: 1.2em;
        font-weight: bold;
    }
    
    ul li::marker {
        content: "✓ ";
    }
    
    ol li::marker {
        font-family: 'Georgia', serif;
    }
    Modern Browsers (Chrome 86+, Firefox 68+, Safari 11.1+)

    ::backdrop

    Selects the backdrop that appears behind fullscreen or dialog elements.

    /* Style dialog backdrop */
    dialog::backdrop {
        background: rgba(0, 0, 0, 0.8);
        backdrop-filter: blur(5px);
    }
    
    /* Style fullscreen video backdrop */
    video:fullscreen::backdrop {
        background: black;
    }
    Modern Browsers (Chrome 37+, Firefox 47+, Safari 15.4+)

    Logical Selectors

    :is(selector1, selector2, ...)

    Matches any element that matches at least one of the selectors in the list. Reduces repetition and takes the specificity of the most specific selector.

    /* Without :is() - repetitive */
    h1 a, h2 a, h3 a {
        color: blue;
    }
    
    /* With :is() - cleaner */
    :is(h1, h2, h3) a {
        color: blue;
    }
    
    /* Complex example */
    :is(.header, .footer, .sidebar) :is(h2, h3) {
        font-family: 'Arial', sans-serif;
    }
    
    /* Multiple contexts */
    :is(article, section) :is(p, li) {
        line-height: 1.6;
    }
    Modern Browsers (Chrome 88+, Firefox 78+, Safari 14+)

    :where(selector1, selector2, ...)

    Works like :is(), but always has zero specificity. Useful for low-priority default styles.

    /* Zero specificity - easy to override */
    :where(h1, h2, h3) {
        color: gray;
    }
    
    /* This will override the above despite lower selector count */
    h1 {
        color: red;
    }
    
    /* Default link styles (easy to override) */
    :where(a:not([class])) {
        color: blue;
        text-decoration: underline;
    }
    
    /* Reset with zero specificity */
    :where(ul, ol) {
        list-style: none;
        padding: 0;
    }
    Modern Browsers (Chrome 88+, Firefox 78+, Safari 14+)

    :not(selector1, selector2, ...)

    Negation pseudo-class. Modern browsers support multiple selectors in :not().

    /* Single selector (all browsers) */
    button:not(.primary) {
        background: gray;
    }
    
    /* Multiple selectors (modern browsers) */
    input:not([type="submit"], [type="reset"], [type="button"]) {
        border: 1px solid #ccc;
    }
    
    /* Exclude multiple classes */
    div:not(.header, .footer, .sidebar) {
        padding: 20px;
    }
    
    /* Complex negation */
    li:not(:first-child):not(:last-child) {
        border-top: 1px solid #eee;
    }
    All Browsers (single selector), Modern Browsers for multiple selectors (Chrome 88+, Firefox 84+, Safari 9+)

    :has(selector)

    Parent selector - selects elements that contain at least one element matching the selector. Revolutionary feature for CSS.

    /* Select parent if it contains specific child */
    div:has(> img) {
        display: grid;
        place-items: center;
    }
    
    /* Style form if it has invalid input */
    form:has(:invalid) {
        border: 2px solid red;
    }
    
    /* Card with image vs without */
    .card:has(img) {
        display: flex;
    }
    
    .card:not(:has(img)) {
        text-align: center;
    }
    
    /* Style article if it has h2 heading */
    article:has(h2) {
        margin-top: 2em;
    }
    
    /* Select label for checked checkbox */
    label:has(+ input:checked) {
        font-weight: bold;
        color: green;
    }
    
    /* Complex example - parent of hovered element */
    ul:has(> li:hover) {
        background: #f0f0f0;
    }
    Modern Browsers (Chrome 105+, Firefox 103+, Safari 15.4+)

    Specificity

    CSS specificity determines which styles are applied when multiple rules target the same element. Specificity is calculated as a four-part value: (inline, ID, class/attribute/pseudo-class, element/pseudo-element).

    Selector Specificity Calculation
    * (0, 0, 0, 0) Universal selector has no specificity
    p (0, 0, 0, 1) 1 element
    .class (0, 0, 1, 0) 1 class
    #id (0, 1, 0, 0) 1 ID
    div p (0, 0, 0, 2) 2 elements
    .class p (0, 0, 1, 1) 1 class + 1 element
    #id .class (0, 1, 1, 0) 1 ID + 1 class
    a:hover (0, 0, 1, 1) 1 element + 1 pseudo-class
    a::before (0, 0, 0, 2) 1 element + 1 pseudo-element
    [type="text"] (0, 0, 1, 0) 1 attribute selector
    div#id.class (0, 1, 1, 1) 1 ID + 1 class + 1 element
    :is(#id, .class) (0, 1, 0, 0) Takes highest specificity (ID)
    :where(#id, .class) (0, 0, 0, 0) Always zero specificity
    :not(.class) (0, 0, 1, 0) :not() itself has zero, but its argument counts

    Specificity Rules

    Calculation Order

    Specificity is compared from left to right. A selector with higher specificity in any category wins.

    /* (0, 1, 0, 0) - ID wins */
    #header {
        color: red;
    }
    
    /* (0, 0, 1, 1) - Class + element loses to ID */
    div.header {
        color: blue;
    }

    Inline Styles

    Inline styles have the highest specificity (1, 0, 0, 0).

    /* This CSS rule... */
    #id .class p {
        color: blue;
    }
    
    /* ...will be overridden by inline style */
    <p style="color: red;">Red text</p>

    !important

    !important overrides normal specificity rules. Use sparingly.

    /* Low specificity but wins due to !important */
    p {
        color: red !important;
    }
    
    /* High specificity but loses */
    #id .class p {
        color: blue;
    }
    
    /* Only another !important with higher/equal specificity can override */
    #id p {
        color: green !important;
    }
    Best Practice: Aim for low specificity in your base styles to make them easy to override. Use classes instead of IDs for styling. Avoid !important except for utility classes or debugging.

    CSS Nesting

    Native CSS nesting (introduced in 2024) allows you to nest selectors within other selectors, similar to preprocessors like Sass. The & symbol represents the parent selector.

    Basic Nesting

    Nest child selectors within parent selectors for better organization.

    /* Traditional CSS */
    .card {
        padding: 20px;
    }
    
    .card h2 {
        color: red;
    }
    
    .card p {
        color: gray;
    }
    
    /* With CSS Nesting */
    .card {
        padding: 20px;
    
        h2 {
            color: red;
        }
    
        p {
            color: gray;
        }
    }
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)

    Parent Selector (&)

    Use & to reference the parent selector. Required when the nested selector doesn't start with an element.

    /* Pseudo-classes and pseudo-elements require & */
    .button {
        background: blue;
    
        &:hover {
            background: darkblue;
        }
    
        &:active {
            transform: scale(0.95);
        }
    
        &::before {
            content: "→ ";
        }
    }
    
    /* Modifiers */
    .button {
        padding: 10px;
    
        &.primary {
            background: green;
        }
    
        &.secondary {
            background: gray;
        }
    }
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)

    Compound Selectors

    Combine the parent selector with additional classes or attributes.

    .card {
        background: white;
    
        /* .card.featured */
        &.featured {
            border: 2px solid gold;
        }
    
        /* .card[data-state="active"] */
        &[data-state="active"] {
            box-shadow: 0 0 10px blue;
        }
    
        /* .card:not(.disabled) */
        &:not(.disabled) {
            cursor: pointer;
        }
    }
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)

    Multiple Levels of Nesting

    Nest selectors multiple levels deep, but avoid going too deep for maintainability.

    .navigation {
        background: #333;
    
        ul {
            list-style: none;
    
            li {
                display: inline-block;
    
                a {
                    color: white;
    
                    &:hover {
                        color: yellow;
                    }
                }
            }
        }
    }
    
    /* Compiles to:
       .navigation { background: #333; }
       .navigation ul { list-style: none; }
       .navigation ul li { display: inline-block; }
       .navigation ul li a { color: white; }
       .navigation ul li a:hover { color: yellow; }
    */
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)

    Media Queries in Nesting

    Nest media queries inside selectors for component-scoped responsive styles.

    .sidebar {
        width: 300px;
    
        @media (max-width: 768px) {
            width: 100%;
        }
    
        h2 {
            font-size: 1.5em;
    
            @media (max-width: 768px) {
                font-size: 1.2em;
            }
        }
    }
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)

    Contextual Parent References

    Reference parent selector in different contexts.

    .theme-dark {
        background: black;
    
        .button {
            background: #333;
            color: white;
        }
    }
    
    /* Alternative using & for specificity */
    .button {
        background: white;
        color: black;
    
        .theme-dark & {
            background: #333;
            color: white;
        }
    }
    
    /* Compiles to: .theme-dark .button { ... } */
    Modern Browsers (Chrome 112+, Firefox 117+, Safari 16.5+)
    Note: CSS nesting is a relatively new feature. For broader browser support, consider using a CSS preprocessor like Sass or PostCSS with the postcss-nesting plugin. Keep nesting depth reasonable (3-4 levels max) to maintain readability and avoid high specificity.