The class selector
A class selector is a dot followed by a class name. It styles every element whose class attribute contains that name, whatever the element type.
The dot appears only in CSS. In HTML the attribute is class="badge", without a dot. Class names are case sensitive: .Badge does not match class="badge".
Multiple classes on one element
An element can carry any number of classes, separated by spaces. Each one brings its own rules, which is how you build variants from small pieces:
.btn.danger, with no space, matches elements that have both classes. The last span has danger but not btn, so the chained rule skips it.
Class selector variants
| Selector | Matches |
|---|---|
.note | Any element with class note |
p.note | Only <p> elements with class note |
.btn.primary | Elements with both btn and primary |
.card .title | A .title anywhere inside a .card |
.card > .title | A .title whose parent is a .card |
.a, .b | Elements with a or b |
The difference between the space and no space is covered with more combinators on the CSS selectors page.
The ID selector
An ID selector is a hash followed by the id: #site-header styles the element with id="site-header". An id must be unique in the page, so an ID selector targets exactly one element.
Ids do more than style: href="#details" scrolls to the element, <label for="email"> points at an input's id, and JavaScript finds it with document.getElementById('details'). That is the usual reason to give an element an id; for styling, a class is the better tool.
Class vs ID
Class .name | ID #name | |
|---|---|---|
| Per page | Many elements | One element |
| Per element | Several, space separated | One |
| Specificity | (0,1,0) | (1,0,0) |
Link target (#name in a URL) | No | Yes |
| Best for | Styling | Anchors, labels, JavaScript hooks |
The specificity gap is the practical reason to style with classes. One ID beats any number of classes, so a rule written with an ID can only be overridden by another ID, an inline style or !important:
Adding and removing classes with JavaScript
Classes are the normal way for JavaScript to change how something looks: the CSS defines the states, the script only switches them.
classList also has add, remove, contains and replace. Avoid assigning className directly: it replaces every class the element had.
Naming classes
- Letters, digits, hyphens and underscores are safe:
card,card-title,card__title,is-open. - Do not start a selector with a digit or a hyphen followed by a digit.
.2colis invalid CSS. Start with a letter (.cols-2) or escape the digit (.\32 col). - Name by purpose, not by look:
.errorsurvives a redesign,.red-textdoes not. - A naming convention helps on larger projects. BEM writes
block__element--modifier, for example.card__title--large.
Common mistakes
- Putting the dot in HTML.
class=".badge"never matches.badge. - Two
classattributes.<p class="a" class="b">keeps onlya. Useclass="a b". - A space when you meant both classes.
.btn .primarylooks for a nested element;.btn.primaryis the same element. - Reusing an id. Duplicate ids break
getElementById, anchor links and label associations, even if the CSS seems to work. - Styling everything with ids. Their specificity makes later overrides painful; use classes.
Frequently Asked Questions
How do you select a class in CSS?
Write a dot followed by the class name: .card { ... } styles every element with class="card". The dot is only in the CSS; the HTML attribute has no dot.
What is the difference between a class and an id in CSS?
A class can be used on any number of elements and an element can have several; an id must be unique in the page and an element has at most one. In CSS, #id has much higher specificity than .class, so ID rules are harder to override.
How do I give an element two classes?
Separate the names with a space in one attribute: class="btn primary". Writing class twice on an element does not work; the browser keeps only the first attribute.
How do I select an element that has two classes?
Chain the class selectors with no space: .btn.primary matches elements that have both classes. With a space, .btn .primary means a .primary element inside a .btn element.
Can a CSS class name start with a number?
In HTML it can, but a selector cannot begin with an unescaped digit, so .1col is invalid CSS. Escape the digit (.\31 col) or, better, start class names with a letter.