Types of Selectors
CSS offers many ways to target elements, from broad to extremely specific.
/* Type selector — targets all <p> elements */
p { margin: 0; }
/* Class selector — targets elements with class="card" */
.card { border: 1px solid #ddd; }
/* ID selector — targets the single element with id="header" */
#header { background: #333; }
/* Attribute selector — targets inputs with type="email" */
input[type="email"] { border-color: blue; }
/* Descendant selector — targets <a> anywhere inside .nav */
.nav a { text-decoration: none; }
/* Direct child selector — targets <li> that are direct children of .nav */
.nav > li { display: inline-block; }
/* Pseudo-class — targets <a> only while hovered */
a:hover { color: orange; }
/* Universal selector — targets everything */
* { box-sizing: border-box; }
A practical guideline for choosing selectors:
- Use classes for anything reusable across multiple elements — this is the most common and flexible choice.
- Use IDs sparingly, mainly for unique page landmarks or JavaScript hooks, since ID-based rules are hard to override later (high specificity).
- Use type selectors (
p,h1) for broad, page-wide resets or defaults. - Combine selectors to be precise:
.card h2targets<h2>only inside elements with classcard, without needing a new class name for every heading variant.
Overusing IDs or writing overly long combined selectors (div.container ul.list li.item a.link) makes CSS brittle — prefer flat, class-based rules wherever possible.