Descendant Selectors: Styling Nested Elements
When you first start learning CSS, it can feel confusing to control exactly which parts of your page get styled. You might want to color links in your navigation bar one way, and links in your footer another way. How do you do that without changing all the links?
That’s where descendant selectors come in.
In this article, you’ll learn what descendant selectors are, how to write them, and how to use them to style nested elements (elements inside other elements). We’ll go step by step with simple examples you can copy, paste, and experiment with.
What is a Descendant Selector?
In HTML, elements can be inside other elements. For example, a <p> (paragraph) can be inside a <div>, or a <span> can be inside a <p>. We say the inner element is a descendant of the outer one.
In CSS, a descendant selector lets you style elements that live inside another element. The basic pattern looks like this:
outer inner {
/* styles go here */
}
outeris the ancestor (the parent, grandparent, etc.).inneris the descendant (the child, grandchild, etc.).- The space between them means: “any
innerelement insideouter, no matter how deep.”
For example:
div p {
color: blue; /* Make all paragraphs inside any div blue */
}
This does not affect paragraphs that are not inside a <div>.
Example 1: Styling Paragraphs Inside a Container
Let’s start with a very simple HTML structure:
<!-- Example 1 HTML -->
<div class="container">
<h2>Welcome</h2>
<p>This paragraph is inside the container.</p>
</div>
<p>This paragraph is outside the container.</p>
Now let’s write CSS that only styles the paragraph inside .container:
/* Example 1 CSS */
.container p {
color: darkgreen; /* Text color */
font-weight: bold; /* Make the text bold */
}
What’s happening here?
.containerselects any element withclass="container".pselects paragraph elements..container p(with a space) means: “select all<p>elements inside elements with the class.container.”
Expected result:
- The first paragraph (inside
.container) will be dark green and bold. - The second paragraph (outside
.container) will look normal.
Try it yourself
- Change
darkgreentoredand see what happens. - Add another
<p>inside the.containerand confirm it also gets styled. - Add a
<p>somewhere else on the page and confirm it does not get styled.
Example 2: Styling Links Inside a Navigation Menu
A very common use of descendant selectors is styling navigation menus. Let’s say you have this HTML:
<!-- Example 2 HTML -->
<nav class="main-nav">
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
<p>Read more <a href="#more">here</a>.</p>
We want:
- Links in
.main-navto look like menu items. - Other links (like the one in the paragraph) to keep the default style.
Here’s the CSS:
/* Example 2 CSS */
.main-nav a {
text-decoration: none; /* Remove underline */
color: white; /* White text */
background: #0077cc; /* Blue background */
padding: 8px 12px; /* Space around the text */
margin-right: 8px; /* Space between links */
border-radius: 4px; /* Slightly rounded corners */
}
What’s happening here?
.main-nav aselects all<a>(link) elements that are inside an element with classmain-nav.- Only the menu links inside the
<nav class="main-nav">are affected. - The link in the paragraph stays unchanged, because it’s not inside
.main-nav.
Expected result:
- The menu links will look like button-style navigation items.
- The “here” link in the paragraph will look like a normal link.
Try it yourself
- Change
background: #0077cc;to another color and see how it looks. - Add another
<a>link inside.main-navand watch it automatically get styled. - Add a new
<nav class="footer-nav">and confirm its links don’t get the.main-nav astyles.
Example 3: Nesting Multiple Levels Deep
Descendant selectors work even if elements are nested several levels deep. Consider this HTML for a simple “card” component:
<!-- Example 3 HTML -->
<div class="card">
<h3>Article Title</h3>
<p>This is a short description of the article.</p>
<p>Read the <a href="#full-article">full article</a>.</p>
</div>
<div class="card">
<h3>Another Title</h3>
<p>Another description.</p>
<p>Visit our <a href="#blog">blog</a>.</p>
</div>
Now we’ll style only the links inside cards:
/* Example 3 CSS */
.card a {
color: #cc3300; /* Dark orange text */
font-weight: bold; /* Bold text */
}
Why this is powerful
Notice that in the HTML, the links are inside <p> tags, which are inside .card divs.
The selector .card a doesn’t care how many levels deep a is nested. It just means:
“Find any
<a>element that is anywhere inside an element with classcard.”
Expected result:
- Only the links inside
.cardelements will be dark orange and bold. - Links outside
.cardelements (if you add any) will not be affected.
Try it yourself
- Add an
<a>link directly under the.card(not inside<p>) and see that it still gets styled. - Add a
<div><a>Nested</a></div>inside the.cardand see that it’s styled too. - Then add a link after the
.cardsections to confirm it stays default.
Example 4: Combining Class and Element Descendants
You can also combine classes and elements for more precise control. Let’s imagine a layout with a sidebar and a main content area:
<!-- Example 4 HTML -->
<aside class="sidebar">
<h2>Sidebar</h2>
<p>Check out these links:</p>
<a href="#profile">Profile</a>
<a href="#settings">Settings</a>
</aside>
<main class="content">
<h1>Welcome to the site</h1>
<p>Here is an important <a href="#update">update</a> you should read.</p>
</main>
Say we want:
- Sidebar links to be small and subtle.
- Content links to be larger and more eye-catching.
We can do this:
/* Example 4 CSS */
.sidebar a {
font-size: 0.9rem; /* Slightly smaller text */
color: #555; /* Dark gray color */
}
.content a {
font-size: 1.1rem; /* Slightly larger text */
color: #006600; /* Dark green color */
font-weight: bold; /* Bold text */
}
What’s happening here?
.sidebar atargets links inside the sidebar..content atargets links inside the main content.- The same HTML tag (
<a>) behaves differently depending on where it lives in the page.
This is a core idea in CSS: you can reuse the same HTML elements, but use context (like sidebar vs. main content) to change how they look.
Try it yourself
- Move a link from
.sidebarinto.contentand see how its style changes. - Add another area, like
<footer class="footer">, and create a.footer a { ... }style.
Common Mistakes to Avoid
Here are a few things beginners often run into with descendant selectors:
Forgetting the space
.containerpis not the same as.container p..containerpmeans “an element with classcontainerp,” which is not what you want.
Expecting direct children only
.card amatches anyaelement anywhere inside.card, no matter how deep.- If you only want elements that are direct children, you’d use a different selector (
>), but as a beginner, focus on simple descendant selectors first.
Overusing global selectors
- Writing
p { color: red; }changes all paragraphs. - Using
.container p { ... }gives you more control and avoids surprises.
- Writing
How to Practice Descendant Selectors
Here’s a simple way to get comfortable with them:
- Create a new HTML file on your computer.
- Add a few sections, like header, nav, main, sidebar, and footer.
- Put some paragraphs and links in each section.
- Write CSS using descendant selectors to:
- Color paragraphs differently in each section.
- Style links differently in different areas.
- Make headings inside certain containers stand out.
As you experiment, you’ll start to “see” the structure of the page and how selectors connect to that structure.
Quick Recap & What’s Next
Let’s recap the key points:
- A descendant selector uses a space between two selectors, like
.container p. - It means: “select all elements that match the second selector and are inside elements that match the first selector.”
- Descendant selectors work no matter how deeply nested the elements are.
- They let you style the same HTML element differently depending on where it appears in the page.
You’ve just learned one of the most important tools in CSS: targeting specific parts of your layout based on structure. That’s a big step—well done.
Next steps:
- Keep practicing with more nested structures.
- Learn about other selector types like child selectors (
>), class selectors (.class), and ID selectors (#id). - Try combining them to create powerful, precise styles.
Every small experiment you do builds your confidence. Keep going, keep testing ideas, and soon descendant selectors will feel completely natural.
