CSS Best Practices – 14 Steps to Become a CSS Ninja Pt1

CSS Best Practices - 14 Steps to Become a CSS Ninja Pt1

Table of Contents

CSS can be hard to manage even for professional web developers. In this two-part series, you will learn about 14 CSS best practices. In this first part, you will learn how to master CSS specificity hierarchy. You explore the dangers of !imporant declarations and ID selectors. You will also learn about the costs of using overqualified selectors. Finally, you will learn how to avoid browser inconsistencies. Learn how to manage CSS like a professional CSS developer and become CSS ninja!

No.7-14 are in part 2.

No.1: Master CSS specificity hierarchy

Let’s start this article about CSS best practices with the toughest one. If you are serious about becoming a CSS ninja, there is one thing you have to master. This thing is called CSS specificity hierarchy. You should learn about this even if you don’t want to be a ninja. If your goal is to blow away your colleagues and friends in web development. Then, this is a piece of knowledge you must have. There is a high number of people who call themselves web developers or web designers.

Often neglected basics

What’s interesting is that many of these people know nothing about this topic. These people build websites and web apps without knowing how CSS actually works. They know something about cascade and maybe how browsers read selectors (right to left). Imagine you would know someone who have decent knowledge about cars. Would you ask this person to build you a car? Since you like yourself and don’t want to die, probably not.

Sure, knowing CSS specificity hierarchy is not matter of life or death. Still, if you need to find someone to build you a website, you should look for professional. If you agree with me, real professional is someone who wants to master his craft. This kind of person is obsessed with knowing every detail of his work. What if CSS specificity hierarchy is one of these details? Also, what if CSS specificity hierarchy is of the CSS best practices? Then, person ignoring this “detail” can’t be real professional.

Therefore, if you want to become a CSS professional, you have to learn about this. In addition, if you want to become CSS ninja, you have to master it. You have to know everything about CSS specificity. When a small kid ask you on it, you have to be able to explain it to her. I know that this is quite unlikely to happen, just like a rainbow. Still, your potential client or potential employer might ask you about this. This topic is quite good way to test one’s knowledge.

As we discussed, there are a lot of developers knowing little or nothing about CSS specificity hierarchy. Therefore, this subject can be useful for employers to find hidden gems. It would be interesting to ask people on websites such as Freelancer about this. How many people could answer this question?

The hard things about CSS specificity hierarchy

So, if CSS specificity is so important, why it is one of the most ignored parts of CSS. In addition, why only so little sources covering CSS best practices talk about it? One of the problems might be that, in order to work with CSS specificity, you need to do a bit of math. In this hierarchy, every CSS selector has some specific value. In addition, when you combine selectors, this value goes up. Therefore, simple element selector (a) has lower specificity than two element selectors (a span).

The universal CSS selector has the lowest value. Value of this selector is equal to zero. Literally any selector can beat it. Next is one element. This has value of one. Then, there is element with pseudo-element. This combination has value of two. This goes on and on. The highest value belongs to combination of element selector, ID selector, class selector and element selector. This combination has value equal to 112. By the way, one ID selector is close second with value of 100.

Let me give you a quick overview of CSS specificity hierarchy. Below, you find simple table to help you quickly find hierarchy for your situation. This table will give you quick overview without having to calculate everything on your own. Do you want to get deeper into this topic? Do you want to master the first of CSS best practices. Then, take a look at this very short article I wrote about it. Otherwise, here is the table to which you can always return.

CSS specificity hierarchy table:

* – 0
p – 1 (one element)
li:first-of-type – 2 (one element, one pseudo-element)
ul li – 2 (two elements)
ul ol + li – 3 (three elements)
h1 + *[href*=index] – 11 (one attribute, one element)
ul ol li.list-item – 13 (one class, three elements)
li.list-item.list-item-inline – 21 (two classes, one element)
<p style=””></p> – 1000 (one inline styling)
p – 1 (one HTML selector)
article p – 2 (two HTML selectors)
.class – 10 (one class selector)
div p.class – 12 (two element selectors and a class selector)
#id – 100 (one id selector)
html #id .class p – 112 (element selector, id selector, class selector, element selector; 1+100+10+1)

No.2: Avoid use of !important declaration

The second item on my CSS best practices list is related to specificity hierarchy. Well, the next two CSS best practices are related to it as well. I hope that this shows you how important knowing CSS specificity hierarchy is. Anyway, this CSS best practice is about never using !important declaration. Why I think that banning !important must be among CSS best practices? The reason is that it leads to downward spiral you can’t escape from. What do I mean?

When the crap hits the fan

Imagine a situation when you work with someone who used !important declaration. You would have to work with someone else because you would never do that. Anyway, let’s say that you have to override the style with !important declaration. What can you do? Well, you have a number of options you can choose from. First, you can take the risk and remove the !important used by your colleague. The problem is that it can break something.

If you wanted, you could remove that declaration. Then, you would do a test to make sure everything is okay. However, this would take certain amount of time. So, the question is, is it worth it? The second option is to use your knowledge of CSS specificity hierarchy. The only way to beat this declaration is to increase the hierarchy of selectors. Let’s say that your colleague used it to style span element with a specific class. Fortunately, he used only this one class to style that span.

This means that you have to beat one class selector. This selector has value of 10. To achieve this, you can use following options. First, use two element selectors and a class selector. Second, one id selector. Third, element selector, id selector, class selector, element selector. As you will learn in a minute use of IDs is not among CSS best practices. Therefore, you are left with only one suitable option. What does it mean for you?

You have to use two element selectors and a one class selector. Otherwise, you would have to break other CSS best practices.

Solving the !important problem

The example I used may not look like a big issue. Yes, I agree with you. What will happen if you find yourself in situation when you have to override !important again? This is the problem with important. The first one is always only entrance ticket for another. This is what I meant when I was talking about downward spiral. You use one !important and soon you will have to use another one. I believe that the only way to avoid this spiral is by avoiding !important.

Dealing with !important declaration is similar to dealing with drugs. The best thing to do is to stick to CSS best practices and never start with it. Otherwise, you are asking for troubles. This is why I want to encourage you to use CSS linter. It is easy to forget this practice. Therefore, using some tool, like this linter, to check your code can be very useful. In addition, if you are using Gulp, you can use packages like gulp-csslint or gulp-sass-lint. Remember, automate what you can.

No.3: Don’t use IDs

Another item on CSS best practices list is to never use IDs for styling elements. What are the main reasons for including this among CSS best practices? First, IDs are not re-usable. You can have only one element with specific ID on one page. Therefore, if you want to style more elements on the same page, you have to use more IDs and lines of CSS. Second, this is the beginning of a downward spiral. Yes, I am talking about troubles with CSS specificity hierarchy. We discussed this at length in the previous practice about !important.

The third argument against IDs is that they usually refer to specific elements. The problem is if you want to keep your CSS short and reusable. Then, keeping your styles too specific is not a good idea. In a fact, your goal is the opposite. You want to make your styles more abstract and generic. This will help you use the same style repeatedly. Since you can have more than one specific ID per page, this goal of re-usable CSS is impossible to achieve.

Wait, what about performance?

It is true that ID selectors are faster than class selectors. If you have 1,000 rules, the performance of IDs will be about one millisecond better. One likely reason for this is that you can have only one specific ID selector one a page. Yet, I don’t think that the performance benefit you will gain is significant. Also, keep in mind that this benefit appears only when you reach at least 1,000 rules. This is quite big number that is often out of reach in case of smaller projects.

Another thing we must think about is what impact will extra ID selectors have on the performance. Meaning, as soon as you add any other ID selector, the performance benefit is gone. Also, if you want to get any performance gains you have to avoid adding any selectors after the ID. What will happen if you add another selector, like class or element? Browser reads CSS from right to left. This means that additional selector is scanned as first. This negates the speed of having an ID.

In conclusion, the only way to get any performance gains is by using selector composed of only ID. Also, you have to have a lot of CSS rules in order to make these gains visible. Since 1,000 rules will give you one millisecond, you should aim for around 100,000 rules. This could hypothetically give you about 100 milliseconds. Another thing is how much time will it take the browser to scan and render so many CSS rules. Hence, you should stick to these CSS best practices and avoid use of IDs.

When it’s okay to use IDs?

There is one thing I want to mention before we will move to another practice. Yes, I am advocate of getting rid of IDs from your CSS or Sass stylesheets. However, that doesn’t mean that you should remove IDs from HTML markup entirely. There is one specific use case for IDs. I like to use IDs for JavaScript. As we discussed, IDs are a little bit faster. You can speed up you JavaScript, a bit. Also, JavaScript has a specific method, getElementById().

This method is dedicated to getting elements via ID attribute. You can use IDs as unique identifiers for elements that need extra functionality. Another benefit of this approach is that you will keep your CSS and JavaScript separated. When you remove class from an element, you don’t have to worry about breaking some JavaScript. All your JavaScript is safely bind only to IDs. Still, I have to admit that I don’t like to use IDs in my workflow at all.

When I want to bind some JavaScript, I will rather use class with “js-” prefix. This helps me distinguish between classes for styling and classes for JavaScript. Nowadays, I use IDs only in one case. This is when I want to bind anchor tag to some element on the page via href attribute. When I want to force the page to scroll to certain place when user clicks on that anchor tag. Aside from this case, I see no reason for using IDs.

No.4: Avoid overqualified elements

Number four is: avoid overqualified elements as much as you can. I promise that this is the last of CSS best practices related to CSS specificity hierarchy. What overqualified element means? This is when you use overly complex selectors to style an element. Let’s say you want to style anchor tag that should look like a button. The way that is in line with these CSS best practices is to use something like btn class. Your CSS or Sass stylesheet will contain something like .btn { … }.

When you use overqualified selector, the result will look like a.btn { … }. More extreme example could be a.btn.btn-big.btn-primary { … }. The point is that using element selector is not necessary. The same is usually true for those extra classes. You can use just the .btn class. There are three reasons for avoiding overqualified selectors. First, you will reduce the size of your CSS and you will have to write less CSS. Second, you will improve the selector performance.

The problem with overqualified elements

As I mentioned a couple of times, browser scans CSS from right to left. Also, browser looks for the element after each selector. For example, let’s say you have article h1 { … }. In this case, browser will first look for all h1 tags. Then, it will look for all h1 tags that are also nested inside article tag. Now, what about button example? Browser will look for elements with class .btn-primary. Then, it will look for elements with class .btn-primary and .btn-big. The same for .btn and a selector.

As you can see, browser will have to do four cycles just to render one button. How efficient is this? Imagine you want to buy for small things. Would you go to the shop four times? You would probably make an effort to grab everything at once. When you use just one class or selector you will do the same thing. As a result, browser will have to go only through one cycle. Then, it will render the button as you wish without any time loses.

I suppose that you want to make your website as fast as possible because your goal is great user experience. Avoiding overqualified elements will help the browsers to render CSS faster. Faster CSS rendering will mean faster loading of your site. This is your goal. Therefore, avoiding overqualified elements means achieving your goal of creating great user experience. Sweet and simple. There is nothing you should have to think about. Now on to the next one.

No.5: Reset or normalize

Let me ask you one question. When you start new project, do you reset all elements to some default style? If not, I suggest that you make this part of your workflow. Why? Different browsers tend to render some CSS styles in a different way. This leads to smaller or bigger inconsistencies in design. As a result, your website may look a little bit different in Chrome, Firefox and in Edge. Imagine that surprise when you present project to your client and layout of the website is broken.

You can solve this by making sure browsers render all elements more consistently. This means that you can do two things. First, you can reset all elements by yourself. The problem is that this is time-consuming. Also, if you do this for every project, it is not effective. Then, there is the second way. You can use pre-made CSS stylesheet that will take care of this. Let’s say you chose this option. In that case, you have to include this reset stylesheet before your main. That’s it.

To reset or normalize

I like that you want to stick to these CSS best practices. However, when you decide to choose the second, you have to consider one more thing. What stylesheet will you use to get rid of those browser inconsistencies? There are currently two stylesheets you can choose from. The first one is Normalize stylesheet created by Nicolas Gallagher and Jonathan Neal. Your second option is Reset stylesheet created by Eric A. Meyer.

Now, before you flip a coin to make this decision easier, you should know about something. These two stylesheets are not the same. Both follow different approach to removing browser inconsistencies. Normalize targets only the styles that need normalizing. Also, aims to preserve default styles, not erase them completely. It contains some small fixes to improve usability. Lastly, it is relatively modular. You can extract or remove sections you don’t need.

Reset stylesheet takes a little bit different approach. It sets homogenous visual style by removing all styles and set generic defaults for almost all elements. It literally strips away all styles such as bolds or italics and so on. As a result, strong, em and span looks pretty much the same. In this sense, reset is like a sledgehammer or ram. Normalize is like a scalpel. Reset stylesheet uncompromisingly resets everything. Normalize resets only what’s necessary.

As a result, these stylesheets also differ in the amount of code and also in filesize. Well, these differences are not so significant. However, these differences do exist. Anyway, which one should you choose? That depends on what approach do you prefer. If you want to do a hard reset, reset will be the best choice. If you want something less brutal, choose normalize. Also, don’t forget about usability improvements included in normalize. My personal choice? Normalize.

No.6: Don’t reset (or normalize) everything

Okay, let’s assume you agree that resetting or normalizing CSS should be one of CSS best practices. Don’t rush into downloading and implementing reset or normalize stylesheet. This doesn’t mean that you shouldn’t follow the previous practice. Not at all. I want you to consider whether you really need the whole thing. Both, normalize and reset, contains styles for a lot of elements you will not use in your current project. Therefore, it is not necessary to bloat your CSS with this code.

My advice, and also the sixth CSS best practice, is to customize that pre-made stylesheet. You should pick only the styles that you really need and get rid of the rest. Sure, few extra lines of CSS will don’t have significant impact on performance or filesize. However, that doesn’t mean you should waste with resources. If your goal is great user experience, you should look for every opportunity to optimize your website. Well, this is one of these opportunities.

Keep in mind that these stylesheets are built in a way to work in wide range of conditions. This means that the half of the code is not useful for your project. Also, it is likely that your own styles may override some of this code. These duplicates are safe to be removed. Another reason for dissecting and customizing these stylesheets is gaining a better understanding. When you take reset or normalize stylesheet apart, you will see what is inside.

As a result, you will learn more about how they work, at least roughly. Keep in mind that these stylesheet are maintained by professional web developers. You can learn a lot just by looking and playing with the code. And, who knows, it may help you decide which stylesheet is better for you.

Closing thoughts on CSS best practices

These are all CSS best practices I have for you today. I’m sure that these six CSS best practices will help you improve the quality of your CSS code. Let’s quickly a recap. First, master CSS specificity hierarchy. This is often neglected part of CSS. However, you saw today that many of the best practices are connected to it. Second, avoid use of important declaration. Also, don’t use IDs for styling. These two things lead to downward spiral you will have no chance to escape from.

Next was avoiding overqualified elements. Overqualified elements force the browser to go through more cycles than is necessary to render your styles. This can reduce the performance and harm user experience. Finally, use reset or normalize stylesheet to avoid browser inconsistencies. However, make sure to customize these stylesheet for your specific conditions. Otherwise, you will bloat your CSS with unnecessary code. That’s it.

If you liked this article, please subscribe so you don't miss any future post.

If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂

By Alex Devero

I'm Founder/CEO of DEVERO Corporation. Entrepreneur, designer, developer. My mission and MTP is to accelerate the development of humankind through technology.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.