PortiBlog

3 levels of CSS-selectors to select all elements

22 oktober 2018

Style-facts part3

This chapter in the series of StyleFacts is about how you can select your element-'weapon of choice': The selector. You will see how selectors can be specified for the right cascading effect. You will learn how to overwrite selectors and how to apply selectors on element indirectly by pseudo-selectors. We can select elements. We can select behavior of elements, by selecting the state. We can even select elements that are not really there. That’s where you will reach the last level of selectors the pseudo-element. Let's see which level of selection is most suited to apply your styles: the selector, pseudo-selector or the pseudo-element selector.

Like most of you might have experienced, writing styles is a balancing act between writing too specific style selectors (which only target one thing) and selectors that are too global (which mess up every thing they hit.)

.page-container div

This for instance. Where 'div' is the most widely used element targeting a random 'div' within a global class, will target every 'div'-element on your page. Selecting every class and element along your way to the target, will be the opposite scenario. This is not an efficient way to target the item to be styled. It gives you massive stylesheets that target very little each time.

Types of selectors:

So which type of selectors are there? In styling we have 5 types of selectors. I listed them for you in the preferable order of use:

Class

.class-selector {}

The most preferable selector in my opinion, it targets elements with the class specified after the dot.

Element

element-selector {}

The element-selector weaker then the use of a class-selector and target element types directly.

Attribute

element[attribute="selector"] {}

It is weaker(less specific) then the use of an element-selector and is written between brackets '[]'.

Universal

element > * {} /* universal selector*/

Is not specified to an element or a class. It's a powerful selector, so be careful to use in a global way. it's presented by an asterix.

ID

#idSelector {}

Strongest selector out there which can be used. This is also it's problem. If you use a ID-selector in a combination selection. It can overpower a lot of similar combinator descent selections. This is a nice bridge to combinators. It is combining the types of selectors above into a selection.

 

Combinators:

When you combine classes, they will become more specific. This way you can target classes that are nested deeper in your template, without effecting other elements. There are four ways to combine selectors into a combinator: By Descendent, Child, Sibling and General Sibling Combinator. The most known and most used is the Descendent Combinator:

Descendant

.parent-class .descendant-class

This is where a (parent) element and an element in a (few) more nested level is combined in one selector.
The nested level selector does not necessarily need to be a child element of the element targeted by the parent selector. This is how you can skip levels of explicit selectors to get to your target selector, through 'unique' landmarks within your template.

Child

.parent-class > .child-class

While it is not necessary to specify direct child elements as selector, this can be enforced in CSS by chaining the combinator with a chevron (arrow) to the right. This will target all the children with specifics of your second selector.

Sibling

.parent-class + .sibling-class

Since CSS2 arrived we are able to target sibling and general sibling elements with combinators. The sibling selector, with the '+' in the example above, is to target the direct next sibling element of the previous chained selector (element). To target all siblings with the next chained selector a '~' can be used. Like in the example below:

General sibling

.parent-class ~ .general-sibling-class

We learned which types of selectors there are: class, element, attribute, universal and ID-selector. We know how to combine them: via descendent, child or general-/sibling. So we are ready to move on to the selectors which can target elements inexplicit. The so called pseudo-selectors.

 

Pseudo selectors

Pseudo selectors enable you to select element inexplicit based on state or location. For Example: if you want the second child of an element with a certain selector. Another example is selecting an element only when hovered upon. There are many pseudo selectors and every month new ones are added as experimental CSS3 selectors. To check availability, go to www.caniuse.com and enter the selector you want to use to check if the most used browsers support it already.

state

We can divide pseudo-selectors in 2 groups: based on targeting location, or based on a specific state of an element. To illustrate the state group we can view pseudo-selectors in action '<a>' link element. See what I did there? :)
Below you can see an example of a few common link pseudo-selectors, ':hover', ':link', ':visited':

.link-element:link {}
.link-element:visited {}
.link-element:hover {}

In de the codepen you can see this in action by clicking, hovering or visiting the link. All these different colors and appearance of the link are specified separately. Most of these interactive elements in html come with there browser default styling. Without the styling they would be white on a white background and therefor not visible. many more pseudo-selectors are available to define the state of an element. For instance the ':focus'-state when you click on a input field, or the ':checked' state if you select a checkbox or radio button. The full list of pseudo-classes can be found here.

location

The second group of pseudo(-class)-selectors are the selectors to specify the location of the element. You might know the ':first-child' pseudo-selector. This targets the first child of a selected element. So if you have:

.list &gt; div:first-child {} /* selects the first child in the list */

This will select the first child in the element with the [class]-class. It's possible to target the last child in a similar way. You can do this by defining ':last-child'. For every child in between a new pseudo-selector was created. The so called ':nth-child'-selector. This selector gives you the possibility to select one or more child elements. You can even write equations in attributes to select different sequences of child elements. Let me clarify this with an example:

.list > div:last-child {} /* selects the last child in list */
.list > div:nth-child(odd) {} /* selects the odd children in list */
.list > div:nth-child(7) {} /* selects the 7th child in list */
.list > div:nth-child(4n+1) {} /* selects child 1,5,9,etc in list */

This kind of selecting can be handy in list or tables in which all elements and rows are of the same elements. It does not matter if the elements are specified with a class. You can target them either way. In the codepen you can find an example of the nth-child targeting. I made you a sort of nth-child hovering memory game :). Can you find all color duo's by looking at the selectors?
I mentioned that you can add a mathematical equation into the 'nth-child'-selector. Let's take '4n + 1' for example. You might recognize this from math-class at high school. It is similar to 4x +1. It selects each fourth child and then shifts the selection by one. Selecting the next element. This means 1 (4 x 0 +1), 5 (4 x 1 +1), 9 (4 x 2 +1) and so on… here's a detailed blog about the 'nth-child'-selector.

 

Pseudo- elements

Let's move on to pseudo-elements. These where introduced in CSS3 to add decoration to elements semantically correct. For instance adding a icon to a button without adding an empty 'i'-tag or adding targeting a placeholder element that is a invisible element belonging to the 'input'-element. You can see this selector as 'selecting a part of an element.' Normally you would create a new element to do this but now you can target it being part of its original element.
Let's see the pseudo-element in action:

  .selector-class::before {
content: "x";
position: absolute;
display: block;
top: 0;
left: 0;
width: 30px;
height: 30px;
background-color: gray;
}

You can find a full set of pseudo-element-selectors here. What more magical things you can do with pseudo-elements we will discuss in a later chapter of this blog.

karate kid element selection karate kid element selection

You now know what selector you can use in which situation. Where to use the type of selectors, where to use combinators, where to use pseudo-elements and where you can use pseudo-elements. You know the specificity of selectors. The elements selector is the strongest. Then classes. Then pseudo and attributes. You are now ready to select any element on the page.

Like with driving a car, writing elegant CSS-selectors comes by experience in writing styles and playing around with branding. The template will be your canvas. Try to use selectors in new learned ways to see what possibilities you have. You will discover many things you would normally solve with Javascript.

StyleFacts part 1

StyleFacts part 2

If you have questions about selector or you have a great addition to this blog please let me know in the comments! Thanks for reading. The next blog will be about responsive design.

Submit a comment