Table of Contents
Following specific CSS best practices can help you master CSS. It can help you transition from professional developer to CSS ninja. It in this series, you will learn exactly about these best practices. In this second part, you will start with learning how to setup your typography. Then, you will master naming conventions for CSS classes. You will also learn about modularity and DRY code. Lastly, you will find out how to solve the problem with prefixes keep your CSS valid.
No.1-6 in part 1.
No.7: Define typography only once
The first practice in the second part of CSS best practices article is about typography. Regular readers of this blog know that I am a huge fan of typography. I’m convinced that typography is one of the hardest parts of web design. This area is hard to learn, not to mention to master. Digital typography contains a lot of details you have to know very well. Otherwise, its is very likely that the design will not feel right. Well, this is at least my own experience.
Anyway, mastering typography is not the thing we should talk about at this moment. I dedicated whole article to crafting perfect web typography So, if you want to add mastery in typography to CSS best practices, you have to read that. For CSS best practices, we will stick to one simple rule. You should define typography only once. You should not override your default typography styles. Okay, there can be situations where modifying this or that style once or twice is almost acceptable.
Any exception to the Rule?
So, when is it acceptable to break this example of CSS best practices? My immediate answer is that only when you have no other option. What does this mean? Let’s say you are working on design for blog. It will have card layout inspired by Material design. Here is a complete guide to Material design where you can learn how to do that. Since every card is independent module, we can use article element to wrap the content of each card. Content will compose of heading, thumbnail and text.
Every card, or article, is a component of a page that contains independent content. Meaning, content of one card is not dependent on another. In other words, every card is dedicated for different blog post. Therefore, we can use h1 tag for card headings. Usually, you should have only one h1 heading on the page. However, this applies to old HTML structure of div elements. Divs have no semantic meaning. This means that when you put h1 inside div, it means nothing.
On the other hand, if you put h1 inside article, it is something different. Let me put this very simply. Browser will interpret this h1 heading as a part of the article, not the rest of the page. So, if you have five articles on the page, you can theoretically have five h1 headings. As a result, we can use h1 heading for heading in every blog post card. Doing so will is not against HTML5 and its semantics. However, the downside is that it can create one specific problem.
The problem with sometimes too big headings
We usually define headings in the term of large pieces of content. When you plan your typography scale, you have available relatively large real estate. We can take a blog post as an example. There is plenty of space for even very large heading. Let’s say you decide to set your h1 heading to 5.063rem with base font-size of 16 pixels. This means that the font-size of this heading will be 80 pixels. Again, this is okay on a blog post. Imagine the same size on a blog post card. Do you see it?
This font-size will make the heading disproportionally big. It will be literally huge. There are three solution we can use. The first one is changing global typography settings. This one is congruent with CSS best practices we are talking about. The problem is that it will have an effect on every page of the website. All headings will be much smaller. This is something we don’t want. So, maybe we should take a look at the other options. We still have two more in reserve.
The second option is changing heading tag. Here is the thing. Nobody says that blog post card must use h1 for the title of the blog post. Sure, from the view of semantics it would be better to start article with h1 heading. However, no one will want to kill you if you use h2, h3, h4 or even h5 heading. The upside of this solution is that we don’t have to redefine global typography settings. Therefore, we will not influence any other pages of the website.
Semantics, CSS best practices and exceptions
What if you actually care about semantics. What if you want to follow HTML and CSS best practices? Then, there is the option number three. We can use one line of CSS to override styles for heading placed inside blog post cards. I would suggest using specific class to do this. Otherwise, if you use CSSLint, overriding heading using element selector would cause some errors or warnings. The downside of this option is that we will break one best practice.
Let’s be clear. No one died from breaking one or two CSS best practices. In addition, if the upsides outweigh the downsides, breaking some practices can be a good thing. First, you don’t have to change global typography settings of your project. Therefore, you don’t have to worry about breaking the layout on other pages. Second, you keep your HTML semantically correct. Then, when you use one of the available online tool for outlining your HTML code, your code should pass.
Typography settings following CSS best practices
Let’s say you want to follow these CSS best practices. Then, you should dedicate some place to your typography settings. On this place, you should define default styles for all typography elements for your project. You can put there styles for all headings, paragraphs, strong, ems, links, lists and so on. Then, you should never have to override these styles. Well, in the best-case scenario. This will help you achieve consistency in your design.
No.8: Use descriptive class names
Typography is behind us. Now on to the next one, right? Let’s talk about one of the CSS best practices to make your CSS clearer. By clearer I mean more comprehensible class names. The truth is that it is easy to find examples of CSS classes only its author can understand. I worked on a huge number of projects. In a few rare cases, working on CSS was almost impossible without the help of previous developer or documentation. This is not the right way to work with CSS and classes.
Create classes people will understand
When you create CSS classes you should create them in a way others can understand them. People should be able to guess what the class does just by reading it. They should also know when and how to use it. This doesn’t mean that you should be able to describe exactly what it does in the smallest details. However, you should never need to look at docs, or talk to other developer. This means that CSS classes should be descriptive.
So, if you have a class for styling buttons, it should contain string like btn or button. Many frameworks use classes such as btn-primary, btn-secondary, btn-danger or btn-success. You don’t need to know anything about the framework or web development. Still, you have at least some idea about the result of using these classes. The same for applies to other components of website. You can use .heading-big, .heading-small, .nav, .nav-primary, .nav-social, .link-active, .link-inactive.
All these examples have one thing in common. All of them suggest how to use the class in the right way. I think that it is quite hard to misuse classes such as .btn-primary, nav-main or text-uppercase. All of these classes are very straightforward. You can understand many of them even if you don’t speak English and have just a dictionary. Can you say the same about your CSS? How your CSS classes look like? Could some one from the outside understand your CSS?
Beyond just CSS best practices
If not, you have something to work on. You should consider adding this rule on your list of CSS best practices. This goes beyond just CSS. You should apply this practice to any code you write. If you write JavaScript code, other developers should not need a documentation to understand it. Also, it should make sense to them developers without having to talk to you. The easiest way to test this is by showing your code to your colleagues and other developers. Then, just listen.
Don’t go over the edge
The last thing I want to quickly mention is that you should not take this practice to extremes. There is a fine line between descriptive classes that are concise and over-descriptive classes. The problem is that finding this line can be difficult. Some classes, such as .btn-danger or .link-inactive, are descriptive with using just two words. Other classes, such as .progress-meter-text, .stacked-for-medium or .footer-button-to-top, may require three or more words.
The only way to find the edge is by experimenting. The best will be trying different classes and asking other people for feedback. Give it some time and practice. Soon, you will sharpen your ability to find the best classes with the right length.
No.9: Stick to one naming convention
Let’s stay with CSS classes for a moment. One of the goals of CSS best practices is keeping your CSS maintainable. One way to achieve this is by sticking to one naming convention. Do you remember the classes I mentioned in the previous practice? All examples were using dashes to break the words. There was not a single underscore. Also, all examples were in lowercase. Next, all classes were using the same structure – element followed by modifier (.btn-primary, .nav-main).
All these characteristics make CSS more maintainable. These characteristics make CSS also more predictable and easier to follow. So, when you bring someone else on your team, she can start working very quickly. Furthermore, if you stick to one style, you don’t have to constantly check her work. It doesn’t matter where her skills are or how familiar is she with your project. If she follows the same naming conventions, your CSS will look the same.
Even if you work solo, sticking to one naming convention will be beneficial. You will not have to think about what structure should CSS classes follow. No longer will you have to always think about dashes or underscores. The same is true for lowercase, camel case or uppercase. You decide to follow one naming convention and then you repeat it in every project. As a result, you can dedicate your time to more important activities like designing and code.
No.10: Use BEM
Using BEM notation may not be related to CSS best practices. However, it is still related to naming conventions. So, I decided to at least quickly mention it. BEM is of the naming conventions you can use for CSS classes. The name of this methodology is abbreviation for block, element and modifier. These are the three building blocks of BEM. It also uses dashes and underscores. What’s the main goal of BEM? It aims to help developers understand the relationship between the HTML and CSS.
This is achieved by using those three building blocks and those two symbols. In BEM, block is the highest level of a component. This can be .nav, .sidebar or .btn (navigation, sidebar, button). You can think about this block as a parent element. Next are child elements placed inside it. These elements use the name of parent block followed by two underscores and the name of the element. For example, .sidebar__list, .nav__link, .btn__icon.
The last piece of the puzzle is modifier. Modifiers change property of the block or element without changing the component itself. In other words, modifiers allow you to style the component while keeping the default styles untouched. You do this by adding two hyphens to the name of the block or element. For example, .btn–primary, .list–inline, .icon–small, .heading–big. It may be difficult to get your head around this. However, we have already a lot to discuss.
This is the bad news. The good news is that I wrote a crash course on BEM for web developers. In this article, you will learn everything you need master BEM. Who knows? Maybe, you will decide to implement this as one of the CSS best practices you want to follow.
No.11: Keep your code DRY
I guess that everyone with some experience with programming heard about the DRY acronym. It is a one of the tips veteran programmers and coders give to beginners. As a result, it just had to one of the CSS best practices. The DRY acronym stands for “Don’t Repeat Yourself”. Yes, it is pretty simple. The same is true for the goal of this practice. Part of this practice is regularly refactoring your code. This means going through your code and look for cases when you repeat some code.
When you find some duplicate code, you should replace it with something reusable. In case of CSS, this means creating new class and putting these styles into it. Then, when you need to use those styles, you will not re-write them. Instead, you will use that CSS class. As other CSS best practices, this too has limits. You don’t have to create new classes for styles used only two or three times. Otherwise, you would have class for everything. That’s why I should introduce next best practice.
No.12: Embrace modularity
One way to keep your CSS DRY and sane is by embracing modularity. You should think about most of the elements on the page as modules or components. In a fact, this is the approach frameworks like Bootstrap and Foundation follow. Buttons, cards, lists, modals, forms, tooltips? These all are examples of modules or components. They all share one key characteristic. They are all reusable. The styles of list, button or modal don’t depend on the page. You can use them everywhere.
This means that you don’t have to write the same CSS code again and again. Instead, you use the right class and your job is done. There are many methodologies to help you make your CSS modular. You can use SMACSS, OOCSS, ITCSS or Atomic design. Some of these methodologies are easier to learn and follow. Other may be a bit harder. Also, chances are that one methodology will suit your needs and approach better than others. As a result, I can’t tell you which one is the best.
Well, I can at least tell you what methodology am I currently using. My pick is Atomic Design. Regular readers of this blog probably know this. It is not too long since I published a crash course on Atomic Design. So, if you are interested in this methodology, this will help you get started. Whatever methodology will you choose, your goal is still the same. You want to reduce the amount your CSS. In this sense, modularity and DRY practice goes hand in hand.
No.13: Check your prefixes often
How often do you use vendor prefixes? If are not afraid of experimenting with cutting-edge CSS, your answer is probably Often. How often do you check these prefixes? Prefixes are only temporal solution for using latest CSS features. Once browsers implement some feature, they will start to ignore prefixes for this feature. As a result, these prefixes become useless. Well, not only that. All these outdated prefixes will become a ballast that can impact performance.
This doesn’t mean that you should stop using prefixes. In addition, it also doesn’t mean that you should stop using latest CSS features. Doing so would only slow down the adoption of these features. Why? Because they would be used less often. Therefore, it is in our best interest to use these features to push the rate of adoption. Yet, this doesn’t solve the problem with bloated CSS caused by having outdated prefixes. What can we do about it?
You should do a regular check of your CSS and remove the prefixes that are no longer useful. However, in case of bigger project, this can be quite tedious and time-consuming. For this reason, I recommend that you use tool like autoprefixer or prefix-free. These tools not only add prefixes to experimental CSS features. They also remove outdated ones. Don’t wait. Automate the whole process. As a result, following these CSS best practices will be easier.
No.14: Validate your CSS
The last practice I want to share with you is simple. Always validate your CSS. Just like with linting, using CSS validator will help you keep your code clear of errors. In addition, CSS validator is configured to follow common CSS best practices established by W3C consortium. So, before you hand of your code to your client or employer, make sure to test it. Your output code should be always valid and error-free. As a result, your clients, employer and colleagues will love you.
Bonus no.1: Do you need to use a preprocessor?
Sass, Less, PostCSS. I will bet you hard about at least one of these name. CSS preprocessors have been around for a while. Many developers swear by them. My current choice is Sass (SCSS). However, I’m quite interested in experimenting with PostCSS. Anyway, this section is not about my favorite preprocessor. Here, I want to answer one specific question. Do you need to use preprocessor or not? My answer is No. You don’t NEED to use preprocessor.
It is easy to see people interested in web design asking for advice on the best preprocessor. Is it better to use Sass, Stylus or Less? What about PostCSS? What is the best tool? Before we can try to answer any of these questions, we have to ask one thing. How well do you know CSS? Many people are trying to master preprocessors without knowing CSS well. That’s insane! Imagine you would want to learn how to drive a racing car before learning how to drive properly.
Let’s say you know how to use pedals, steering wheel and how to start the engine. Would you jump right into racing car and went to the track? Probably not. Chances are that you would either not drove too far or kill yourself. Why do you want to do similar thing with CSS? Don’t get me wrong. I like preprocessors. I even wrote a quick tutorial on learning Sass. Preprocessors are powerful. They can help you improve your workflow and effectiveness of your work.
With great power comes great responsibility
However, with this power also comes responsibility. When you don’t know CSS best practices or basic CSS, you can do a lot of damage. Add preprocessors to it and the amount of damage can be exponentially higher. The easiest and common example to demonstrate the power of preprocessors is nesting. In pure CSS, you can’t nest selectors. You have to use multiple consecutive selectors to achieve this. Unfortunately, this is easy when you use preprocessors.
I saw a couple of times people nesting more than five levels deep. As a result, the CSS may look like this: html .wrapper header .nav li a { … }. The problem is that you don’t see this when you use preprocessors. Well, you don’t see it exactly in this way. This is probably why it is so easy to go over the edge with nesting. This is just one of the examples when preprocessors can get out of control. This is why, I think, every developer should master CSS first. Preprocessors can wait.
Do you really need a preprocessor?
Let’s get back to the original question. Do you need to use preprocessor? My answer is No. You don’t have to use preprocessor if you don’t want to. Using any preprocessor is voluntary decision. It says absolutely nothing about the level of your skills. You don’t have to feel embarrassed if you decide not to use it. I worked with great web developers who used only pure CSS. No matter how many preprocessors would you use, you could never beat these guys.
I think that this subject of preprocessor is similar to looking for the best tool. How often do we ask other people about what’s the best tool to do X? What’s the real goal of this question anyway? Do we think that finding the best tool will magically 10x our skills? If so, we are delusional. Skills don’t depend on the tool. If you know how to draw, it doesn’t matter if you use pen, pencil, brush or stick. Neither of these tools will improve or worsen your skills.
You may need some time to get used to your new tool. Let’s say you are used to working with Photoshop and switch to sketch or Affinity Designer. Then, your first tries can be a bit less precise. However, that doesn’t mean that your skills got worse. You are just not used to that new tool. When you learn to work with it, you will see that your skills are still the same. Understand that your skills and tools are separate topics. Therefore, you don’t have to use preprocessors.
If you are bad at CSS, preprocessor will not magically improve your skills. If you are CSS god (nickname my client gave me), not using preprocessor will not make you less great. So, no, you don’t need to use preprocessor.
Bonus no.2: Should you lint or not?
There is also the ongoing discussion whether developers should use linting tools. In the scope of this article we will stick to CSS and JavaScript. Proponents of linting argue that it will help you write cleaner and less buggy code. Opponents of linting tools say that these tools are imposing rules that are too strict. There is some truth. When you decide to start using one these tools you are forced to follow set of rules. However, how much strict those rules are depends on two important factors.
Two factors you have to keep in mind
The first factor is the specific tool you are going to work with. Let’s talk about JavaScript. There are currently three main players: JSLint, JSHint and ESLint. JSLint is the oldest and probably the most strict. It was created by Douglas Crockford. The upside of this tool is that it comes configured. So, you can use it immediately. The downside is that it comes configured and you can’t change it. So, what if you don’t like some rules? You can either use different tool or get used to it.
JSHint and Eslint allow you to use custom settings. Therefore, if you don’t like some rule it is not the end of the world. All you have to do is create your own config and use that. In the case of CSSLint, I mentioned today, the same is true. You can turn on or off any rule. As a result, you can customize it to follow CSS best practices that you think are meaningful.
The second factor determining how strict the rules are is you. Only you can determine how strict rules will you follow. Sure, some linting tools don’t allow you to change the configuration. However, you don’t have to use them. There are usually other alternatives you can use instead. If not, you can create your own. However, this is not important.
Are we asking the wrong question?
I think that we are trying to answer wrong question. We should not ask whether linting is good or bad. Linting is only one practice just like following any of these CSS best practices. What should we ask instead is whether we understand these rules. It is one thing to lint your code and correct all errors and warnings. Something else is actually understanding why are these changes useful. When you decide to change something, you should know why are you doing it. This is what’s important.
This is also why I can’t agree neither with proponents nor with opponents of linting. I don’t think any of these groups addresses the right problem. They are trying to find the best approach to writing clean code. However, the problem is not in cluttered or buggy code. The real problem is knowledge. Think about it. When do you usually make mistakes? It is when your knowledge about some subject is not deep enough. In other words, it is when you are just learning the thing.
Linters will help you keep your code clean and error-free. However, linters will not tell you the why. This is the problem that deserves our attention. I always encourage developers to use linters. However, they also have to understood why this or that line of code was throwing a warning or error. Otherwise, linting doesn’t make a lot of sense. What I mean is that you will not learn anything. You may memorize the rule, but that’s definitely not the same as understanding the why.
So, should you lint?
You have to be able to make a judgment about whether to change the code or not. So, should you lint or not? My answer is Yes. Using linters to check your code is a good way to keep it in best shape. However, you should learn why to you should follow those rules. The same is true for these CSS best practices. First, you must understand the why. Learn the background of these CSS best practices. Then, you can decide to follow them or on. Linting is good, but only with understanding.
Closing thoughts on CSS best practices
Congrats! You’ve just finished this series about CSS best practices. I hope these 14 practices will help you master working with CSS and become CSS ninja. There is a lot to cover when it comes to CSS. Hopefully, I chose the practices that will help you solve the biggest pains and make CSS your favorite subject. There is one last thing I want to say. Decide for yourself which of the CSS best practices will you follow. This is up to you. Remember, working with CSS can be pleasure.
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 🙂