CSS Selectors

Selectors tell CSS which HTML elements to style. Mastering selectors is fundamental to writing efficient CSS.

Basic Selectors

CSS
/* Universal selector — all elements */
* { box-sizing: border-box; }

/* Element selector — all instances of an element */
p { color: #333; }
h1 { font-size: 2rem; }

/* Class selector — elements with class="card" */
.card { background: white; border-radius: 8px; }

/* ID selector — element with id="main" (use sparingly!) */
#main { max-width: 1200px; margin: 0 auto; }

/* Multiple classes */
.card.highlighted { border: 2px solid gold; }

/* Element + class */
p.intro { font-size: 1.2em; font-style: italic; }

Attribute Selectors

CSS
/* Has attribute */
a[target] { color: red; }

/* Exact attribute value */
a[target="_blank"] { color: orange; }

/* Starts with */
a[href^="https"] { color: green; }  /* HTTPS links */
a[href^="mailto:"] { color: blue; } /* Mailto links */

/* Ends with */
a[href$=".pdf"] { color: red; }     /* PDF links */
a[href$=".zip"] { color: orange; }  /* ZIP files */

/* Contains */
a[href*="example"] { color: purple; }
img[alt*="photo"] { border: 1px solid #ccc; }

/* Multiple attribute conditions */
input[type="email"][required] { border-color: red; }

Pseudo-class Selectors

CSS
/* User interaction */
a:hover { color: red; }           /* Mouse over */
a:active { color: darkred; }      /* Being clicked */
a:visited { color: purple; }      /* Already visited */
input:focus { border-color: blue; outline: 2px solid blue; }
input:disabled { opacity: 0.5; cursor: not-allowed; }
input:checked { accent-color: green; }

/* Structural pseudo-classes */
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2n) { background: #f5f5f5; }    /* Even rows */
li:nth-child(2n+1) { background: #fff; }     /* Odd rows */
li:nth-child(3) { color: red; }              /* 3rd item */
p:not(.special) { color: gray; }

/* Form pseudo-classes */
input:valid { border-color: green; }
input:invalid { border-color: red; }
input:placeholder-shown { color: #999; }

Pseudo-element Selectors

CSS
/* Double colon :: (single :: also works) */
p::first-line { font-weight: bold; }
p::first-letter { font-size: 2em; float: left; }

/* Insert content */
.quote::before { content: "\201C"; font-size: 3em; }  /* Opening quote */
.quote::after { content: "\201D"; font-size: 3em; }   /* Closing quote */

/* Custom bullet points */
ul li::marker { content: "→ "; color: blue; }

/* Tooltip on hover */
.tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    background: #333;
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
}
.tooltip:hover::after { opacity: 1; }

Combinators

CSS
/* Descendant (space) — all descendants */
div p { color: blue; }           /* All <p> inside <div>, any depth */

/* Child (>) — direct children only */
div > p { color: red; }          /* Only direct <p> children */

/* Adjacent sibling (+) — immediately following */
h2 + p { margin-top: 0; }       /* <p> right after <h2> */

/* General sibling (~) — all following siblings */
h2 ~ p { color: gray; }         /* All <p> after <h2> */

Knowledge Check

4 questions — test your understanding

1

What does `li:nth-child(2n)` select?

2

What is the difference between `div p` and `div > p`?

3

What does `::before` pseudo-element do?

4

What does `input:focus` select?