#id
Selects the element with the given identifier from its id attribute. It carries very high specificity, so its rules are hard to override later.
Example
##faq {
padding: 12px;
border-radius: 12px;
transition: background-color 0.3s;
}
#faq:target {
background: rgb(124 58 237 / 0.2);
outline: 2px solid #a78bfa;
}<p style="margin: 0 0 10px;"><a href="#faq" style="color: #c4b5fd;">Jump to the FAQ</a></p>
<section id="faq">
<strong>Frequently asked questions</strong>
<p style="margin: 4px 0 0; color: #a1a1aa;">This section has id="faq". Click the link above and it gets highlighted.</p>
</section>Click the link in the preview. The address then ends in #faq, and the section matches the :target pseudo-class.
Definition and usage
#An ID selector starts with a #: the rule #cart { … } hits the element with the attribute id="cart". An ID should be unique across the whole document, so a selector like this usually points to exactly one element.
Its specificity is (1, 0, 0). A single ID beats any number of classes, which is why rules written with # are hard to override later. That’s why most teams style components with classes and save IDs for anchors, form labels (<label for>), and JavaScript.
IDs come in handy for in-page navigation. The link href="#pricing" scrolls to the element with id="pricing", and that element then matches the :target pseudo-class, which you can highlight. Case matters, and an ID that starts with a digit needs to be escaped in CSS.
If you need to target an element by its ID without raising the specificity, use the attribute selector [id="cart"] (class weight) or :where(#cart) (zero weight).
Syntax
##identifier { property: value; }Notation variants
#- The element with
id="logo". A class with the same name doesn’t match, because it’s a completely different attribute. (1, 0, 1)
The ID as an anchor point: everyspaninside#menu. The whole rule picks up the weight of the ID.(0, 1, 0)
The attribute selector hits the same element, but weighs as much as a class, not an ID.(0, 0, 0)
The same element with zero weight. Even a plain type selector overrides a rule like this.
Notation variants in practice
##logo
id="logo". A class with the same name doesn’t match, because it’s a completely different attribute.#logo { background: #7c3aed; color: #fff; }[id="logo"]
[id="logo"] { background: #7c3aed; color: #fff; }:where(#logo)
:where(#logo) { background: #7c3aed; color: #fff; }Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Reach for classes when styling. Save IDs for anchors, form labels, and scripts, and use them sparingly in CSS.
- Don’t repeat the same
idon a page. The browser tolerates the mistake, butgetElementById,<label for>labels, and anchors will only work for the first such element. - Highlight sections that anchor links point to with the
:targetpseudo-class. The user will immediately see where they landed.
Related entries
#- .classSelects elements that have the given class in their class attribute. The most commonly used selector for styling components.
- [attribute]Selects elements by an HTML attribute and its value: exact, starting, ending, a fragment, or a word from a list.
- SpecificityA selector’s weight, which decides which rule wins when several rules set the same property on the same element.
- :where()Works like :is(), but always has zero specificity. Ideal for base styles that should be easy to override.
- A BA space between selectors selects B elements anywhere inside element A, at any depth.
Spotted a mistake or missing an example? Write to us.