10. CSS Selectors continued

Descendant Combinator

The descendant selector or, more accurately, the descendant combinator, lets you combine two or more selectors so you can be more specific in your selection method. For example:

This declaration block will apply to all elements that have a class of box that are inside an element with an ID of container. It’s worth noting that the .box element doesn’t have to be an immediate child: there could be another element wrapping around .box, and the styles would still apply.

Look at the following repl.it:

When we apply the CSS to this HTML example, the only element that’ll be affected by those styles is the first <div> element that has a class of box. The <div> element that has a class of box-2 won’t be affected by the styles. Similarly, the second <div> element with a class of box won’t be affected because it’s not inside an element with an ID of container.

You should be careful when using the descendant combinator in your CSS. This kind of selector, while making your CSS a little easier to read, can unnecessarily restrict your styles to a specific context. In this case, the styles are restricted to boxes inside of #container, which can make your code inflexible.

 

Child Combinator

A selector that uses the Child Combinator is similar to a selector that uses a Descendant Combinator, except it only targets immediate child elements.

For example:

This is the same code from the Descendant Combinator example, but instead of a space character, we’re using the greater-than symbol (or right angle bracket, >).

In this example, the selector will match all elements that have a class of box and that are immediate children of the #container element. That means, unlike the Descendant Combinator, there can’t be another element wrapping .box. It has to be a direct child element.

Take a look at this repl.it:

In this example, the CSS will apply only to the first <div> element that has a class of box. As you can see, the second <div> element with a class of box is inside another <div> element. As a result, despite it too has a class of box, the styles will not apply to that element.

Again, selectors that use this Combinator can be somewhat restricting, but they can come in handy such as when styling nested lists.

 

General Sibling Combinator

A selector that uses a General Sibling Combinator matches elements based on sibling relationships. That is to say, the selected elements are beside each other in the HTML.

This type of selector is declared using the tilde character (~). In this example, all paragraph elements (<p>) will be styled with the specified rules, but only if they are siblings of <h2> elements. There could be other elements in between the <h2> and <p>, and the styles would still apply.

Let’s apply the CSS from above to the following HTML in this repl.it:

In this example, the styles will apply only to the first three paragraph elements. The last paragraph element is not a sibling of the <h2> element because it sits inside the <div> element.

 

Adjacent Sibling Combinator

A selector that uses the Adjacent Sibling Combinator uses the plus symbol (+), and is almost the same as the general sibling selector. The difference is that the targeted element must be an immediate sibling, not just a general sibling. Let’s see what the CSS code for this looks like:

This example will apply the specified styles only to paragraph elements that immediately follow other paragraph elements. This means the first paragraph element on a page would not receive these styles. Also, if another element appeared between two paragraphs, the second paragraph of the two wouldn’t have the styles applied.

So, if we applied this selector to the HTML, this repl.it shows what it would look like:

As you can see in this example, the styles will apply only to the second, third, and fifth paragraphs in this section of HTML.

 

Attribute Selector

The Attribute Selector targets elements based on the presence and/or value of HTML attributes, and is declared using square brackets. Here is an example:

There should not be a space before the opening square bracket unless you intend to use it along with a Descendant Combinator. The above CSS would match this element: <input type="text">. But it wouldn’t match this one: <input type="submit">.

The attribute selector can also be declared using just the attribute itself, with no value, like this:


This will match all input elements with an attribute of type, regardless of the value.

You can also use attribute selectors without specifying anything outside the square brackets (thus targeting based on the attribute alone, irrespective of the element). It’s also worth noting that, when using values, you have the option to include quotes (single or double), or not.

 

Pseudo-class

A Pseudo-class uses a colon character to identify a Pseudo-state that an element might be in. For example, the state of being hovered, or the state of being activated. Let’s look at a common example:

In this case, the Pseudo-class portion of the selector is the :hover part. Here we’ve attached this pseudo-class to all anchor elements (a). This means that when the user hovers their mouse over an element, the color property for that element will change to red. This type of Pseudo-class is a dynamic Pseudo-class, because it occurs only in response to user interaction. In this case, the mouse moving over the targeted element.

It’s important to recognize that these types of selectors do not just select elements; they select elements that are in a particular state. For the purposes of this example, the state is the hover state.

 

Pseudo-element

Finally, CSS has a selector referred to as a Pseudo-element and, when used appropriately, it can be very useful. The only caveat is that this selector is quite different from the other examples we’ve considered. Let’s see a Pseudo-element in context:

This example uses one kind of Pseudo-element, the :before Pseudo-element. As the name suggests, this selector inserts an imaginary element into the page, inside the targeted element, before its contents.