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.
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.
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.
>
)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.
+
)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.
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.
~
)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.
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 hierarchyChild
affects direct child elementsAdjacent
affects adjacent elements and elements placed after a specified elementGeneral Sibling
affects all siblings of a specified elementNow, you have one more skill to add to your CSS toolbelt.
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.
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 — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowNitro.js is a solution in the server-side JavaScript landscape that offers features like universal deployment, auto-imports, and file-based routing.
Ding! You got a notification, but does it cause a little bump of dopamine or a slow drag of cortisol? […]
A guide for using JWT authentication to prevent basic security issues while understanding the shortcomings of JWTs.
Auth.js makes adding authentication to web apps easier and more secure. Let’s discuss why you should use it in your projects.