Before CSS can talk about colors, layout, or animation, it has to answer one question first: which element does this rule apply to? That is the job of the selector, the part that sits right before the curly braces in every style block.
A poorly chosen selector is the quiet cause of half of all visual bugs: a rule that never fires, or one that fires on far more elements than intended. Knowing the main families of selectors avoids these surprises from the very first lines of CSS.
Definition
A CSS selector is the pattern that tells the browser which HTML elements should receive the style declarations that follow. It sits right before the curly braces: selector { property: value; }. It can target a single element, a handful of elements that share a trait, or every single element on the page.
The main families of selectors
CSS offers several ways to designate an element, and they combine with one another. A type selector targets an HTML tag directly, like p or button. The Class selector targets any element carrying a specific class attribute, written with a dot. The ID selector targets a single element through its id attribute, written with a hash sign. The Attribute selector targets an element based on the presence or value of one of its HTML attributes, inside square brackets. The Universal selector, the star, targets absolutely everything on the page.
On top of that, pseudo-classes and pseudo-elements target a state or a rendered fragment rather than a tag, but those two families are rich enough to deserve their own dedicated entries.
A concrete example
/* type selector */
p {
color: #333;
}
/* class selector */
.card {
border-radius: 8px;
}
/* id selector */
#header {
position: sticky;
}
/* attribute selector */
input[type="email"] {
border-color: #999;
}
/* universal selector */
* {
box-sizing: border-box;
}Each of these syntaxes answers a different need. Picking the right selector is not a matter of taste: it is a matter of scope, and of how easy the code will be to maintain later.
Combining selectors
Selector families are not mutually exclusive: they compose. button.primary targets only buttons that also carry the primary class. nav a[target="_blank"] targets links that open a new tab, inside a nav tag. That composition, together with combinators that describe the relationship between two selectors, makes it possible to target an element precisely without ever touching the page's HTML.
| Family | Syntax | Target |
|---|---|---|
| Type | div | Every div tag |
| Class | .button | Any element with class="button" |
| ID | #header | The single element with id="header" |
| Attribute | [type="text"] | Any element carrying that attribute |
| Universal | * | Every element on the page |
The trap of selectors that are too broad or too narrow
A selector that is too broad, such as a bare type selector with no class, touches everything that shares that tag, including elements nobody had in mind at the start. A selector that is too narrow, chaining several classes together or leaning on an id, becomes hard to reuse elsewhere and painful to fix once the page evolves. Our HTML and CSS course walks through these selector choices with concrete examples, to help you write rules that stay easy to maintain months later.
Frequently asked questions
Yes, by separating them with a comma. h1, h2, h3 { margin-top: 0; } applies the same declaration to all three tags without duplicating the style block three times.
A selector designates an element by its nature, such as its type, class, id, or an attribute, while a combinator describes the relationship between two selectors, for example a space meaning descendant or a greater-than sign meaning direct child.
No, but recognizing the main families helps when reading existing code. In everyday work, the class selector alone already covers most of a project's needs.