Chidume Nnamdi I'm a software engineer with over six years of experience. I've worked with different stacks, including WAMP, MERN, and MEAN. My language of choice is JavaScript; frameworks are Angular and Node.js.

What you need to know about CSS combinators

3 min read 946

What You Need to Know About CSS Combinators

In CSS, we use combinators to affect parts of the HTML based on the selector’s relationship. The relationship here is generally parent-child, parent-grandchild, parent-great-grandchild, parent-great-great-grandchild, etc.

Why should you learn CSS combinators?

Learning about combinators makes you better at writing CSS and helps you avoid excessive CSS code. They come in handy when you want to alter HTML to which you don’t have access or that has a huge CSS codebase and too many elements. Combinators can also help you pinpoint the section or part of the HTML you want to style with high accuracy because they are based on the relationships between selectors.

In this guide, we’ll explore various CSS combinators you can use to style your HTML.

Descendant selector (space)

This selector affects the descendants or child selectors of the specified parent selector.

The descendant selector is typically used in theming, which is when you’d want to set the same style on different HTML tags.

div h3 {
    ...
}

This selector is a descendant selector. Notice that it’s denoted by a space. The styling code within the braces will affect only the h3 tags inside divs in the HTML.

div p {
    ...
}

The styling code will affect the p elements inside all div elements.

<div>
    <p>I'm paragraph1</p>
    <ul>
        <li>
            <p>I'm paragraph2</p>
        </li>
    </ul>
<div>
<div>
    <p>I'm paragraph3</p>
<div>
<p>I'm paragraph4</p>

The three p elements — I'm paragraph1, I'm paragraph2, and I'm paragraph3 — will be affected by the styling because they are inside div elements.

In the descendant selector, it will affect the elements no matter what the hierarchy of the parent-child relationship.

In the above code, I'm paragraph2 is not a direct child of the div element, but it is affected because it’s a descendant of the div element. In other words, it’s a grandchild of the div element.



Child selector (>)

The child selector selects only the direct child elements of the specified element. It’s denoted by using the > arrow.

div > p {
    color: orangered;
}

This will set the color of all the direct p child elements of div elements to orange-red.

<div>
    <p>I'm paragraph1</p>
    <ul>
        <li>
            <p>I'm paragraph2</p>
        </li>
    </ul>
</div>
<div>
    <p>I'm paragraph3</p>
</div>
<p>I'm paragraph4</p>

The p elements I'm paragrapg1 and I'm paragraph3 will be set to orange-red because they are direct child elements of the div elements.

I'm paragraph2 is a descendant/grandchild of a div element but not a direct child element, so it was not colored. I'm paragraph4 was not colored because it’s not a child of a div element.

Adjacent sibling selector (+)

This selector selects and affects the elements that are placed after the specified element. It;s denoted by the plus symbol (+).

div + p {
    color: orangered;
}

All p elements placed after a div element will be styled with the color orange-red.

<div>
    <p>I'm paragraph1</p>
    <ul>
        <li>
            <p>I'm paragraph2</p>
        </li>
    </ul>
</div>
<div>
    <p>I'm paragraph3</p>
</div>
<p>I'm paragraph4</p>

Only I'm paragraph4 will be orange-red because it’s placed immediately after a div element, meaning it’s a sibling of the div element.


More great articles from LogRocket:


I'm paragraph1, I'm paragraph3, and I'm paragraph2 are children of div elements. Since they’re not siblings to any div element, they aren’t affected.

Let’s add a fifth p after I'm paragraph4.

<div>
    <p>I'm paragraph1</p>
    <ul>
        <li>
            <p>I'm paragraph2</p>
        </li>
    </ul>
</div>
<div>
    <p>I'm paragraph3</p>
</div>
<p>I'm paragraph4</p>
<p>I'm paragraph5</p>

I'm paragraph5 is a sibling to the div element just like I'm paragraph4, but it won’t be affected with the color because it’s not placed immediately after a div element and therefore is not an adjacent sibling to a div element.

General sibling selector (~)

The general sibling selector selects all siblings of the specified element. It’s denoted by the tilde symbol (~).

div ~ p {
    color: orangered;
}

This will set the color of all p sibling elements and div elements to orange-red.

<div>
    <p>I'm paragraph1</p>
    <ul>
        <li>
            <p>I'm paragraph2</p>
        </li>
    </ul>
</div>
<div>
    <p>I'm paragraph3</p>
</div>
<p>I'm paragraph4</p>
<p>I'm paragraph5</p>

Only I'm paragraph4 and I'm paragraph5 will be affected because they are siblings of a div element.

Conclusion

In this tutorial, we covered all the combinators in CSS: descendant, child, adjacent, and general sibling.

Let’s tick off some key takeaways:

  • Descendant works on child elements and descendant elements, regardless of the child hierarchy
  • Child affects direct child elements
  • Adjacent affects adjacent elements and elements placed after a specified element
  • General Sibling affects all siblings of a specified element

Now, you have one more skill to add to your CSS toolbelt.

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web and mobile apps — .

Chidume Nnamdi I'm a software engineer with over six years of experience. I've worked with different stacks, including WAMP, MERN, and MEAN. My language of choice is JavaScript; frameworks are Angular and Node.js.

Leave a Reply