Learning CSS with Less - CSS Selectors and Selector Specificity

Learning CSS with Less - CSS Selectors and Selector Specificity
We integrated into our Technical Blog section a new project that Andrei, a great developer in our community, wanted to share with all of us. Now, the project consists of a series of courses created by Andrei with a lot of passion and dedication, giving from his knowledge gathered during years of work and sleepless nights the chance to learn, grow and become our best version in the future.
Now lets discover the next part of the course together! Enjoy!
- Topics of discussion
- CSS selector types
- Combining CSS selectors
- Selector specificity
1. Topics of discussion
In this tutorial, we are going to take a look at CSS selectors and how one can compute a selector specificity. So, let's have some fun.
2. CSS selector types
CSS selectors are basically the names you use in your CSS files in order to add certain styles to them. There are three different types of selectors:
- class selectors - these are the selectors we have been using so far and are defined by using the. sign followed by what is known as a class name; these selectors are used in the class attribute for your HTML elements
- HTML element selectors - these selectors can be used in your CSS file by using an HTML element name by itself, e.g. body, p, etc., and adding styles to it, similar to classes; be advised that when using HTML selectors the styles will get applied to all the elements of that certain type unless otherwise specified
- id selectors - these ones make use of the id attribute value which may be added to HTML elements; in order to use an HTML element id in your CSS file, you have to write is as #element_id
Class selectors are very useful when you want to reuse the style defined for one element multiple times or in multiple pages. HTML element selectors can be useful if you are certain that all elements of a certain type need to be styled in some way, though more often than not HTML element selectors are used alongside class selectors.
Finally, id selectors are useful for creating dedicated styles for a certain element and its children, without affecting other areas that might reuse the same classes. Basically, you can use them to override some styles for a certain area in your page without affecting other areas.
3. Combining CSS selectors
CSS selectors can be combined in a number of different ways. We'll see how this is written in regular CSS since it's important to understand the subtle differences between how the instructions are written. We'll also discuss how you can write these instructions using Less CSS to your advantage.
- selector { instructions } - the most basic use, it's the one we have been most accustomed to
- selector1 selector2 ... selectorN { instructions } - when we use multiple selectors separated by a space (e.g. .class1 .class2), the style will get applied to all elements that use class2 and are descendants (or children if you will) of an element that has the class1 CSS class in their class attribute; the styles will get applied to all children and grandchildren that have the class2 element
- ; as you can see, the list-item is used on an element which is a child element for the ul that has the id nav; the styles would not get applied if you had another element with the class list-item inside the li HTML elementselector1 > selector2 ... > selectorN { instructions } - when we use multiple selectors like so (e.g. #nav > .list-item), the style will get applied to all elements that have the list-item class in their class attribute and are direct descendants of the element with the nav id; an HTML sample for this would be
- selector1selector2...selectorN - when using selectors like so (e.g. .class1.class2 or li.list-item), the styles will get applied to elements that have both class1 and class2 in their class attribute or are li HTML elements that have the list-item class; basically, an element has to satisfy all the conditions in the CSS selector group, be it having all the classes, being a certain element with a certain class, being an element with a certain id, etc
So, this is how these rules look like in plain old CSS. What about Less? How does it help you write such selectors in a more manageable fashion? Well, let's find out.
The first selector type from the list above is obviously written in the same way in both vanilla CSS and Less CSS. A group similar to the second one from the list is going to be written like this in Less CSS:
.class1 {
.class2 {
color: blue;
}
}
When compiling this file, the resulting CSS will be .class1 .class2 { color: blue; }.
The third one can be written like this:
.class1 {
& > .class2 {
color: blue;
}
}
And finally, the last selector grouping can be written in Less like this:
.class1 {
&.class2 {
color: blue;
}
}
Make sure to play around with these selectors to see how they work.
4. Selector specificity
CSS specificity can become very tricky, especially when you are using a CSS framework that was not written by you. So, what is this specificity? Well, it refers to how specific a CSS instruction is. It consists of 4 different numbers, determined by the presence or absence of certain selectors or HTML attributes. This specificity is usually written by using those 4 numbers and separating them through a comma, e.g. 1,0,0,0.
Going from the most important specificity value to the least important one, here is how you calculate those numbers:
- presence of the style HTML attribute - if an element has the style attribute defined, then those take precedence over any other CSS instructions passed via the class attribute; this can be overridden and we'll talk about it in a future tutorial; when the style attribute is present, you add a 1,0,0,0 to the CSS specificity of the element
- element id - for every ID used in a CSS selector, you are going to add 0,1,0,0 to the specificity of the element
- class, pseudo-class, and attributes - for each of these you'll add 0,0,1,0 to the CSS specificity of the element; we'll discuss pseudo-classes, attributes, and pseudo-elements in another tutorial
- HTML element or pseudo-element - you'll add 0,0,0,1 for each and every HTML element present in a CSS selector
Let's compute the specificity for some elements now:
- #nav .list-item a - this element uses an id, a class and an HTML element, therefore the specificity of the element is going to be 0,1,1,1
- ul#navigation .list-item a - this element uses an id, a class and two HTML elements, therefore the specificity would be 0,1,1,2
So, why is specificity so important you ask? Well, because there may be times when you apply a CSS class to an element and it will not change the styles of said element. Here is an example. Say you have the following HTML:
And say you have the following CSS:
.list-item {
a {
color: red;
}
}
.main-link {
color: black;
}
Now one would assume that the first element in the list would have black color for the text. Well, sorry to disappoint you, but the color is going to be red. And it's all because of the fact that a higher specificity CSS is setting that color to red. Of course, there is a way around this and we'll get to that when we discuss how we can override CSS rules.
And with that, we conclude this tutorial. In the next one, we will talk about overriding CSS rules. See you then.