DEV Community

Cover image for Working With Combinators
enigma6174
enigma6174

Posted on

Working With Combinators

Sometimes when we are working with CSS we often feel that our selectors aren't good enough to get the job done. We feel the need for more control and be able to design CSS rules targeting more specific aspects of the HTML document. For example, we might have a list of paragraph elements and we want to apply some specific CSS rules only to a select few. Maybe, we want to explain a better relationship between two selectors that enables us to pinpoint specific HTML elements only. This is where combinators come into the picture!

A combinator explains the relationship between selectors.

The name combinator comes from the fact that they combine other selectors in a way that gives them a useful relationship to each other and the location of the content in the document.

Okay, so what does it mean? Well, consider the below example:

#page-header h2 {
  font: red;
} 
Enter fullscreen mode Exit fullscreen mode

Here, the combination of #page-header h2 is called a combinator because they combine the two selectors #page-header and h2 to specify a very particular part of the HTML document. And that particular part (w.r.t. the above example) is the h2 element inside another HTML element which has an id of page-header.

Combinators allow us to be more specific about our rules and select elements by passing more information to the selectors. Remember, we can combine multiple selectors, not just two!

There are 4 main combinators in CSS that we work with and those are all that any developer needs to know about! Let us have a quick look at them below

  • Adjacent Sibling (+)
  • General Sibling (~)
  • Child (>)
  • Descendant

css-combinators

Adjacent Sibling (+)

The adjacent sibling combinator is created by adding a + sign between two (or more) selectors.

This combinator works by a sibling relationship which means that every selector in an adjacent sibling combinator must share the same parent and the second element must come immediately after the first element.

Consider the example below

adjacent sibling example

Only the p tags that immediately follow the h2 tags are the ones where the CSS rule gets applied. There is a p tag that is a sibling of h2 which does not get affected by the CSS rule because it is an immediate sibling of h3 tag!

General Sibling (~)

The general sibling combinator is created by adding a ~ sign between two (or more) selectors.

This combinator also works by a sibling relationship which means that every selector in a general sibling combinator must share the same parent. However unlike the adjacent sibling combinator, general sibling combinator do not require elements to be immediate siblings. All we need to ensure that the second element should come after the first element, but not immediately!

Consider the example below

general sibling example

Here, any p tag that comes after an h2 tag is modified by the CSS rule (that is why even the last p tag which is not immediately after h2 also gets affected!)

Child Combinator (>)

The child combinator is created by adding a > sign between two (or more) selectors.

This combinator works by a parent-child relationship which means that the second element of the combinator is a direct child of the first element. Therefore, the second element in the combinator will always be enclosed directly under the first element.

<body>
  <section>
    <p>Hello</p>
    <span>World!</p>
  </section>
  <div>
    <p>Welcome To Programming!</p>
  <div>
</body>
Enter fullscreen mode Exit fullscreen mode
  • The <section> and <div> elements are direct child of the <body> element.
  • The first <p> and <span> elements are direct child of <section> element and the second <p> element is a direct child of the <div> element.
  • The <p> and <span> elements are not directly wrapped under the <body> element, therefore they are not the direct child of it.

Keeping the above concept in mind, consider the below example

child combinator example

Only the p elements which are direct child of div element get modified by the CSS rule (hence the p inside article is not affected)

Descendant Combinator

The descendant combinator is created by adding a whitespace between two (or more) selectors.

This combinator works by a descendant-child relationship which means that the second element of the combinator is an indirect child of the first element. The second element therefore need not be directly enclosed within the first element.

<body>
  <section>
    <p>Hello</p>
    <span>World!</p>
  </section>
  <div>
    <p>Welcome To Programming!</p>
  <div>
</body>
Enter fullscreen mode Exit fullscreen mode
  • The <section> and <div> elements are direct child of the <body> element.
  • The first <p> and <span> elements are indirect child of <body> element and therefore, the descendants of it.
  • The <p> and <span> elements are not directly wrapped under the <body> element but they are wrapped inside <section> and <div> which are themselves wrapped inside <body> element. This is why <p> and <span> are the descendants of <body>

Consider the below example

descendant combinator example

Every p element that is a descendant of div is modified by the CSS rule (and that is why the p inside article also gets modified!)

More Examples

Consider the example below (the image on the right is the output without CSS)

combinators example

Adjacent Sibling

Select p elements that share the same parent as h2 and come immediately under it

h2 + p {
  background: rgb(211, 28, 28);
  color: white;
  font-weight: 600;
}
Enter fullscreen mode Exit fullscreen mode

adjacent sibling example

General Sibling

Select p elements that share the same parent as h2 and come under it

h2 ~ p {
  background: rgb(211, 28, 28);
  color: white;
  font-weight: 600;
}
Enter fullscreen mode Exit fullscreen mode

general sibling example

Direct Child

Select h2 elements that are directly the child of main element

main > h2 {
  background: rgb(211, 28, 28);
  color: white;
  font-weight: 600;
}
Enter fullscreen mode Exit fullscreen mode

direct child example

Descendant

Select all h2 elements that are descendants of body

body h2 {
  background: rgb(211, 28, 28);
  color: white;
  font-weight: 600;
}
Enter fullscreen mode Exit fullscreen mode

descendant example


That's all folks! This completes a lengthy yet detailed explanation of CSS combinators and all that is there to know about them! Hopefully all your doubts are cleared and you have a good grasp of this concept and if you are still having doubts, feel free to comment!

For the complete CSS and HTML code examples, you can access my Github repo (remember to check the folder combinators for this code)

GitHub logo enigma6174 / css-course

A collection of resources to help learn CSS

Understanding CSS

If you liked this article and want to stay updated with more such articles, support me by following me on DEV and Twitter

I write about web development, AI, cloud, entrepreneurship, technology and anything else that excites me!

Discussion (0)