CSS selectors tell the browser which HTML elements your styles should apply to. Everything in CSS starts with selecting the right element.
Every CSS rule follows this pattern:
selector {
property: value;
}For example:
p {
color: blue;
}Here p is the selector. It applies color: blue to every paragraph element.
Applies to everything:
* {
margin: 0;
}Targets HTML tags directly:
h1 {
font-size: 2em;
}Classes are reusable. You add them in HTML with class="".
<p class="note">Important!</p>.note {
color: red;
}IDs are unique—used for one element only.
<div id="header"></div>#header {
background: black;
}Avoid using IDs for styling large projects. They create high specificity and are harder to override.
These target elements based on their HTML attributes:
input[type="text"] {
border: 1px solid gray;
}More patterns:
| Example | Meaning |
|---|---|
[disabled] |
Has the attribute |
[type="submit"] |
Attribute equals a value |
[href^="https"] |
Starts with |
[src$=".png"] |
Ends with |
[title*="promo"] |
Contains |
Selectors can express relationships between elements.
| Pattern | Example | Reads as |
|---|---|---|
| Descendant | div p |
All <p> inside <div> |
| Child | div > p |
Direct children only |
| Adjacent sibling | h1 + p |
First <p> after <h1> |
| General sibling | h1 ~ p |
Any <p> after <h1> |
Use combinators to describe structure, not just appearance.
Pseudo-classes describe states or positions of elements.
| Example | Meaning |
|---|---|
:hover |
Mouse over |
:focus |
Keyboard focus |
:active |
While clicked |
:visited |
Visited link |
:checked |
Checkbox checked |
button:hover {
background: lightblue;
}Control how elements appear relative to siblings:
li:first-child { font-weight: bold; }
li:nth-child(2n) { background: #eee; }Useful ones:
:first-child,:last-child:nth-child(n),:nth-of-type(n):only-child,:empty:root(the<html>element)
These let you style parts of an element.
| Selector | Purpose |
|---|---|
::before / ::after |
Add generated content |
::first-letter |
Style first letter |
::first-line |
Style first line |
::selection |
Style selected text |
::placeholder |
Style input placeholder |
Example:
p::before {
content: "→ ";
color: gray;
}Apply one rule to multiple selectors:
h1, h2, h3 {
font-family: sans-serif;
}Exclude something:
div:not(.active) {
opacity: 0.5;
}-
:is()– group with specificity preserved.:is(h1, h2, h3) { color: navy; }
-
:where()– like:is(), but zero specificity. -
:has()– select elements based on what they contain.article:has(img) { border: 1px solid #ccc; }
When multiple rules match the same element, CSS decides by specificity.
| Selector Type | Score |
|---|---|
| Inline style | 1000 |
| ID selector | 100 |
| Class / attribute / pseudo-class | 10 |
| Type / pseudo-element | 1 |
| Universal / combinator | 0 |
If specificity ties, the later rule in the stylesheet wins.
- Prefer classes for styling.
- Avoid IDs unless necessary (e.g., anchors).
- Keep selectors short and readable.
- Avoid nesting deeper than 3 levels.
- Use pseudo-classes to reduce extra HTML.
- Use
:where()and:is()to control specificity intentionally.
- Start with basic selectors and classes.
- Experiment with pseudo-classes (
:hover,:nth-child). - Learn combinators (
>,+,~) for structural styling. - Explore advanced selectors (
:is(),:has()) once comfortable. - Always inspect results in browser DevTools to see which selector applies.