CSS Descendant Selector (A B) — Selecting Nested Elements
Learn how the CSS descendant combinator selects elements nested at any depth within an ancestor. Understand specificity, performance, and when to use descendant vs child selectors.
Detailed Explanation
CSS Descendant Selector
The descendant combinator (a space between two selectors) matches elements that are descendants of a specified ancestor, at any nesting depth.
Syntax
/* Select all <a> elements inside .nav */
.nav a {
text-decoration: none;
}
How It Works
The browser reads selectors right to left. For .nav a, it first finds all <a> elements, then checks if each one has an ancestor with the class .nav. The target element can be a direct child or nested many levels deep.
<nav class="nav">
<ul>
<li>
<a href="/">Home</a> <!-- matches .nav a -->
</li>
</ul>
</nav>
Descendant vs Child Selector
| Combinator | Syntax | Depth |
|---|---|---|
| Descendant | A B |
Any depth |
| Child | A > B |
Direct children only |
Specificity
The specificity is the sum of both parts. .nav a = (0, 1, 0) + (0, 0, 1) = (0, 1, 1).
Performance Considerations
Deeply nested descendant selectors like body div ul li a span force the browser to traverse many DOM levels. Prefer shorter, class-based selectors for better performance and maintainability.
Common Patterns
/* Style links inside articles differently */
article a { color: #0066cc; }
/* Reset list styles inside navigation */
nav ul { list-style: none; padding: 0; }
/* Style form labels */
form label { display: block; margin-bottom: 0.5rem; }
Use Case
Descendant selectors are used everywhere in CSS: styling links within navigation bars, targeting paragraphs inside articles, resetting list styles inside specific containers, and styling form elements within fieldsets. They are the most natural way to scope styles to a particular section of the page without adding extra classes to every child element.