A selector is the first part of a CSS rule. It tells the browser: “apply these styles to these elements.” Understanding selectors is the foundation of CSS.
Tag selector
Applies to all elements of that tag.
h1 {
font-size: 2rem;
color: #111827;
}
p {
line-height: 1.6;
color: #374151;
}
a {
color: #2563eb;
text-decoration: none;
}
Careful: rules for p will apply to every paragraph on the page.
Class selector (.)
The most commonly used. A class is assigned via the class attribute.
<article class="post-card">
<h2 class="post-title">FastAPI: Quick Start</h2>
<p class="post-meta">June 12, 2025</p>
</article>
.post-card {
padding: 24px;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.post-title {
font-size: 1.25rem;
margin-bottom: 4px;
}
.post-meta {
color: #6b7280;
font-size: 0.875rem;
}
One element can have multiple classes:
<p class="post-meta tag-python">Python · 5 min</p>
.tag-python {
color: #16a34a;
}
ID selector (#)
An ID is unique — only one element on the page should have a given ID.
<header id="site-header">...</header>
#site-header {
background: #1e293b;
padding: 16px 24px;
}
In real projects, ID selectors for styling are rarely used — classes are more flexible. IDs are mainly for anchor links (<a href="#comments">) and JavaScript.
Combinators
Descendant (space)
/* Any <a> inside .post-card — at any nesting level */
.post-card a {
color: #2563eb;
}
Direct child (>)
/* Only <li> that are direct children of .nav-list */
.nav-list > li {
display: inline-block;
}
Adjacent sibling (+)
/* <p> immediately after <h2> */
h2 + p {
margin-top: 4px;
color: #6b7280;
}
General sibling (~)
/* All <p> elements after <h2> at the same level */
h2 ~ p {
text-indent: 1em;
}
Attribute selector ([attr])
/* All links with target="_blank" */
a[target="_blank"] {
padding-right: 16px;
}
/* All text inputs */
input[type="text"] {
border: 1px solid #d1d5db;
border-radius: 4px;
padding: 8px 12px;
}
/* href contains a substring */
a[href*="github.com"] {
color: #6b7280;
}
Grouping: multiple selectors at once
/* Apply the same styles to h1, h2, h3 */
h1, h2, h3 {
font-weight: 700;
color: #111827;
line-height: 1.25;
}
Specificity: who wins
When multiple rules target the same element, the more specific one wins.
| Selector | Specificity |
|---|---|
Tag (h1) |
0,0,1 |
Class (.card) |
0,1,0 |
ID (#header) |
1,0,0 |
Inline style="" |
1,0,0,0 |
Specificities add up:
.post-card h2 { color: red; } /* 0,1,1 */
.post-title { color: blue; } /* 0,1,0 */
Here .post-card h2 wins — its specificity is higher. More details in the cascade article.
DevBlog: navigation example
<nav class="site-nav">
<a href="/" class="nav-link nav-link--active">Home</a>
<a href="/articles/" class="nav-link">Articles</a>
<a href="/about/" class="nav-link">About</a>
</nav>
.site-nav {
display: flex;
gap: 24px;
}
.nav-link {
color: #374151;
text-decoration: none;
font-weight: 500;
}
.nav-link:hover {
color: #2563eb;
}
.nav-link--active {
color: #2563eb;
border-bottom: 2px solid #2563eb;
padding-bottom: 2px;
}
Summary
| Type | Syntax | Example |
|---|---|---|
| Tag | tag |
p {} |
| Class | .class |
.post-card {} |
| ID | #id |
#header {} |
| Descendant | A B |
.card a {} |
| Direct child | A > B |
ul > li {} |
| Adjacent sibling | A + B |
h2 + p {} |
| Attribute | [attr] |
input[type="text"] {} |
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!