UNDERSTANDING CSS SELECTORS: COMBINATOR SELECTORS
Tags: codenewbie, css, tutorial, webdev
Published: 2020-07-08 11:57:33

Hello, World! Welcome to the third article in my CSS series, Understanding CSS Selectors, a series with aim to give a more enlightening explanation about the use of selectors as selectors are pivotal in carrying out a good project with CSS. In the previous articles, I have given explanations about what selectors are, talked about the 5 types of selectors and we have talked about the four types of the basic CSS selectors  and how they are used and how to navigate specificity with them.

In this article, we would be looking at the **combinator selectors** and how they are utilized in adding styles to the webpage. As we have stated in the previous articles, selectors are patterns used to select the elements you are trying to style. A selector can be used singularly as a simple selector or as a complex selector, in situations, where styling becomes less straightforward which is where combinators now come in.  A combinator is a character that combines two or more selectors in a way that gives them a useful relationship to each other and the location of content in the HTML document. For example, we can target only a particular child element in a parent element or we can target a certain element and it’s adjacent sibling.

CSS combinators are subdivided into four classes; 
1. Descendant Combinator ( )
2. Child Combinator (>)
3. Adjacent Sibling Combinator (+)
4. General Sibling Combinator (~)

We would be looking at each other individually to appropriately explain them.

**The Descendant Combinator** ( )
	The descendant selector is typically represented by a single space ( ) character and is used between the two selectors such that the elements of the second selector will be styled if the first selector corresponds with their ancestor name (a parent, parent’s parent, parent’s parent’s parent, etc.)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7cbnftjgbdgfj3uktmcf.png)

The ancestor selector represents any structurally superior element in the hierarchy, this can be a parent or the parent of a parent and so on. The descendant selector represents any of the descendant element in the hierarchy, it doesn't have to be a direct child.

Let's look at an example of the descendant combinator usage
**HTML**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/00scr7daiq4viigg5uud.png)

**CSS**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7efvc589hyh5h07tkhdb.png)
So from the CSS code above, we would expect only list items with an *a* tag to be coloured blue as the other list items do not have the *a* tag even though they are children of the *ul* tag.

**The Child Combinator** (>)
	The child selector is represented by a greater than (>) character placed between two selectors. It is used to show that the second selector is an immediate child of the first selector.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2ulomxff2txcm6mockhw.png)

The child selector is quite stricter from the descendant combinator because it would not style the elements of descendant tags that are further down the family tree even though they are the same with the second selector.

Let's look at an example of the child combinator usage
**HTML**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f02ettxrurjmw517ob0e.png)

**CSS**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3gcinylye56x6zr28r55.png)
If you run the code above, we would get the first paragraph in blue validating what we have been saying the child combinator but the second paragraph will be coloured red. It would seem that the addition of the combinators increases the specificity of the style properties but this is not necessarily the truth but the reason that style from the *p* selector wasn't effected by the direct descendant *p* elements was because the specificity of the *div > p* was higher because it involves two selectors in contrast to the second selector which involves just one selector.

**The Adjacent Sibling Combinator** (+)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/18w34mje0q43i92krs99.png)
 The adjacent sibling combinator is represented by the plus (+) character placed between two selectors. When the adjacent sibling combinator is used, it targets the second selector which is coming after the first selector. It is used to select the element that is placed right next to another element at the same level of the hierarchy, it's from this property that the adjective  ‘adjacent’ is used which means ‘next to’ or ‘adjoining’.


**HTML**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mnogqmvol03635bwgoc4.png)

**CSS**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/k3haohoxqmbcht8eyk10.png)
From the stylesheet, the styling that would only be effected on the *p* tags are those ones that right next to the *h3* tags.

**The General Sibling Combinator** (~)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4d5f5avy53f81q2m2xrh.png)
	The fourth combinator is the general sibling combinator which is represented by the Tilde operator (~) character. Like the adjacent sibling combinator, the general sibling combinator doesn’t involve the parent but rather sibling tags which are on the same level in the hierarchy. The general sibling combinator selects siblings anywhere within the parent container, it necessarily doesn’t have to be adjacent siblings but the target selector has to come after the first selector.  In other words, if you want to select siblings of an element even if they are not directly adjacent, then you can use the general sibling combinator (~).

**HTML**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ez1whuo9ll95uqv26rnx.png)

**CSS**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vsj5iojbkudintlf1cjn.png)
If you run the code, we have from above you would be able to see that all the *p* tag elements were styled except from the first one although it is at the same level with the *h3* tags but it doesn't come after it. 

There is also a somewhat fifth combinator called the **column combinator** which represented by || between two CSS selectors. It matches only those elements matched by the second selector that belong to the column elements matched by the first. This technology is still in the working draft and is not supported by any browser yet. As for the other combinators, they can supported by almost every version of browsers currently in use. To see the versions that support its use, you can visit www.caniuse.com.

According to the MDN Web Docs on Specificity, the Universal selector (*), __combinators (+, >, -, ' ', ||)__ and the negation pseudoclass(:not()) have no effect on specificity. (The selectors declared inside :not() do, however.)

**Are Combinators really necessary when we can use ID or Class selectors to directly target some elements?**🤷🏾‍♂️🤷🏾‍♂️
The truth is that IDs and Class selectors can directly target elements, which gives us a functional website but they are not efficient enough to handle a complete design. Using the combinators will also help us achieve more flexibility with less code compared to using just the ID or class selectors.

CSS Combinators are great for reducing the amount of extra classes and ID’s in your HTML. The least amount of extra attributes you have in the HTML the better. It will not only reduce the page size but also make maintenance easier.

Thank you once more for reading to the end, see in you in the next article where we would be talking about the __Pseudoclass Selectors__.

Ciao! ❤️