Mudzinga

Curious how websites style only certain parts of a page, like links inside menus or text inside cards? Learn descendant selectors step-by-step and start styling like a pro—read the full guide!

5 Minute Read

Descendant Selectors: Styling Nested Elements

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 */
}
  • outer is the ancestor (the parent, grandparent, etc.).
  • inner is the descendant (the child, grandchild, etc.).
  • The space between them means: “any inner element inside outer, 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?

  • .container selects any element with class="container".
  • p selects 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 darkgreen to red and see what happens.
  • Add another <p> inside the .container and 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-nav to 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 a selects all <a> (link) elements that are inside an element with class main-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-nav and watch it automatically get styled.
  • Add a new <nav class="footer-nav"> and confirm its links don’t get the .main-nav a styles.

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 class card.”

Expected result:

  • Only the links inside .card elements will be dark orange and bold.
  • Links outside .card elements (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 .card and see that it’s styled too.
  • Then add a link after the .card sections 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 a targets links inside the sidebar.
  • .content a targets 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 .sidebar into .content and 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:

  1. Forgetting the space

    • .containerp is not the same as .container p.
    • .containerp means “an element with class containerp,” which is not what you want.
  2. Expecting direct children only

    • .card a matches any a element 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.
  3. Overusing global selectors

    • Writing p { color: red; } changes all paragraphs.
    • Using .container p { ... } gives you more control and avoids surprises.

How to Practice Descendant Selectors

Here’s a simple way to get comfortable with them:

  1. Create a new HTML file on your computer.
  2. Add a few sections, like header, nav, main, sidebar, and footer.
  3. Put some paragraphs and links in each section.
  4. 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.

About Percy Mudzinga

This article was automatically generated by an AI-powered blog system built by Percy.
Percy Mudzinga is a Senior Full-Stack Software Engineer based in Harare, Zimbabwe, with nearly a decade of experience building enterprise web and mobile applications. He specializes in React, Vue.js, Flutter, and Node.js.

Never Miss an Update

Subscribe to our newsletter and get the latest articles delivered directly to your inbox every week.

No spam, unsubscribe anytime. We respect your privacy.

© 2025 Mudzinga. All rights reserved.