Lately, I’ve found many people stumped by CSS, both new and experienced developers. Naturally, they wanted a better language to replace it, and CSS preprocessors were born out of that idea. Some people want to use the CSS framework to write less code (we saw in the previous article why this is not a good idea). Some people have started to abandon CSS and use JavaScript to apply styles.

But you don’t always have to use CSS preprocessors in your workflow. You don’t have to start every project with a bloated framework by default. Anything that uses JavaScript to do what CSS is supposed to do is a scary idea.

In this article, we’ll look at some tips and suggestions for writing better CSS, easier to maintain CSS code, so your stylesheets will be shorter and have fewer rules. CSS will become a convenience rather than a burden.

Select the minimum available selector

# #

CSS is a declarative language that allows you to style DOM elements. In this language, some rules take precedence over others, just as inline styles override previous rules.

For example, if we have the following HTML and CSS code:

 class="button-warning">Copy the code
.button-warning {
  background: red;
}

button, input[type=submit] {
  background: gray;
}Copy the code

Although. Button-warning is defined before button, input[type=submit], it overwrites the latter background property. Why is that? What are the rules that determine which rule overrides the style of the other?

Accuracy.

Some selectors are thought to be more precise: for example, a # ID selector will override a. Class selector. What happens if we apply a selector that is more accurate than it really needs to be? If we want to override these styles later, and we want to override this selector, we need a more precise… Yes, it’s a snowball that eventually becomes difficult to maintain.

So when writing your own selector, ask yourself: Is this the most appropriate selector?

All of the selector accuracy rules have been officially defined in the W3C CSS specification, and you can find the details of each selector here. If you want something simpler to help you understand, read this article.

Don’t add more code to bugs

Let’s consider a common situation: you have a bug in your CSS, and you’ve figured out which DOM element has the wrong style. In addition, you discover that it has a property that it shouldn’t have.

You may want to keep adding more CSS to it, and if you do, your code base will get bigger, making it harder to find bugs later.

Instead, go back and look for bugs, and use your browser’s developer tools to see elements and all their links. Determine which rule is applying the styles you don’t want. Modify existing rules so that they do not produce unwanted results.

In FireFox, you can debug stylesheets by right-clicking on elements on a page and selecting Check Elements.

Look at that cascade in all its glory. Here you can see all the rules applied to the elements in the order in which they are applied. The top rule is more precise and can override the previous style. You can see that some rules have strikelines for some attributes: this means that a more precise rule has overridden the attribute.

Also, not only can you view these rules, you can actually choose whether to apply them or not, but you can also modify them to see the results, which is great for fixing bugs.

The fix may be a rule change or rule change elsewhere in the hierarchy. This may require a new rule. At the very least, you should know that this is the right requirement and a requirement for your code base.

This is also a good time to refactor your code. Although CSS is not a programming language, you should give it the same consideration as JavaScript or Python: it should be clean and readable. Refactor when necessary.

Don’t use it! important

The previous tip is already hinted at, but because of its importance, I want to reiterate it: Don’t use it! Important in your code

! Important is a feature in CSS that allows you to break the cascading rule. CSS stands for “cascading style sheets “, which is also a hint.

! Important is often used when you are in a hurry to fix a bug because you don’t have enough time or don’t want to fix the cascading relationship.

When you give a property application! Important, browsers will ignore accuracy rules. When you are! Important a rule to rewrite another rule as well! Rule important, you’re in big trouble.

In fact, there is also a suitable use! The most important case is when you debug something with a development tool. Sometimes, you need to figure out which value will fix your bug. Use it in your development tools! Important to modify CSS rules, which can help you find the values you need regardless of the cascading feature.

Once you know which CSS works, you can go back to your code and see which layer you should put your CSS in.

Not onlypxand%

Using px(Pixels) and %(percentages) units is intuitive, so we’ll focus here on the lesser-known ones.

Em and rem

The most famous relative unit is the EM. 1em equals the font size of that element.

Let’s consider the following HTML code:


  

Title

One Ring to bring them all and in the darkness bind the.

Copy the code

Add the following rule:

The article {the font - size: 1.25 em; }Copy the code

Most browsers apply a font size of 16px to the root element by default (this feature can easily be overridden, by the way). So the article element above will have a font size of 20px (16*1.25).

What about the h1 element? To better understand what’s going on, let’s add another CSS rule to the stylesheet:

H1 {the font - size: 1.25 em; }Copy the code

Even though it is 1.25em, the same as the article element, we must consider the compound nature of the EM unit. What does that mean? In other words, h1, as a direct child of body, will have a font size of 20px (16*1.25). However, our H1 is inside an element with a font size different from the root element (our article element). In this case, 1.25 refers to the font size given in the cascading relationship, so the font size of the H1 element will be 25px(16 * 1.25 * 1.25).

By the way, to memorize these multiplication chains yourself, you can use the Computed TAB in the Inspector panel, which shows the actual, final pixel values.

The EM unit is actually quite useful because it makes it easy to dynamically change the size of a page (not only the font size, but also other attributes such as line spacing and width).

If you like the relative size of EM, but not its complexity. You can use rem units. The REM unit is very similar to EM, but removes its complexity and uses only the size of the root element.

So if we change the EM unit of our previous CSS h1 to REM

The article {the font - size: 1.25 em; } h1 {font-size: 1.25rem; }Copy the code

Vw and vh

Vw and VH are viewport units. 1vw is 1% of the viewport width, and 1vh is 1% of the viewport height. They are useful when you need a UI element that takes up the entire screen (such as a traditional translucent mask layer) because they don’t always match the size of the body.

Other units

Other units may not be as common or as useful as the ones above, but you are bound to encounter them someday. You can learn more about them in detail (on MDN).

Using flexbox

We discussed this topic in a previous article on CSS frameworks, and the Flexbox module simplifies the work of laying out and aligning objects. If you’re not familiar with Flexbox, check out this introductory article.

That’s right, you can use Flexbox now, unless you really need to support those old browsers for some commercial reason. The current browser approval rating for Flexbox is over 94%. So you don’t have to keep writing floating DIVs, which are so hard to debug and maintain.

Also, keep your eye on the latest Grid module, which will be as pleasant as the breeze.

When using CSS processors…

CSS compilers such as Sass or Less are very popular in front end development. They are extremely powerful tools, and if fully utilized can make you more productive with CSS.

Do not abuse selector nesting

A common feature in these processors is selector nesting, such as the following Less code:

a { text-decoration: none; color: blue; &.important { font-weight: bold; }}Copy the code

Will be translated as the following CSS rules:

a {
  text-decoration: none;
  color: blue;
}

a.important {
  font-weight: bold;
}Copy the code

This feature allows us to write less code and better organize rules to apply elements that would normally be together in a DOM tree. This is also great for debugging.

However, the abuse of this feature can be found everywhere, and the CSS selector ends up repeating the entire DOM, so if we have the following HTML:

 class="post">
  
    
    

Tags: href="..." class="tag">irrelevant

Copy the code

We might find in CSS stylesheets:

article.post { // ... other styling here header { // ... p { // ... a.tag { background: #ff0; }}}}Copy the code

The main problem with these CSS rules is that they are very specific selectors. We already know that’s what we’re trying to avoid. There is also the problem of excessive nesting. I’ve already discussed this in another article.

In short, don’t produce CSS nested rules that you will never enter yourself.

Include VS extensions

Another useful CSS feature is mixin, which is a reusable CSS block. For example, let’s say we want to style a button, and most of them have basically the same CSS properties. We can also create a Less blend like the following code:

.button-base() {
  padding: 1em;
  border: 0;
}Copy the code

Then, create a rule like the following:

.button-primary {
  .button-base();
  background: blue;
}Copy the code

This will generate the following CSS:

.button-primary {
  padding: 1em;
  border: 0;
  background: blue;
}Copy the code

As you can see, this is useful for reusing some common code.

In addition to “including” a mixin, there’s actually another option: “extend” or inherit it (the exact term varies). All it does is merge multiple selectors into the same rule.

Let’s look at an example of using mixin:

.button-primary {
  &:extend(.button-base)
  background: blue;
}

.button-danger {
  &:extend(.button-base)
  background: red;
}Copy the code

This will be translated as:

.button-primary, .button-danger {
  padding: 1em;
  border: 0;
}

.button-primary { background: blue; }
.button-danger { background: red; }Copy the code

Some articles online tell us to just use “include”. Others, however, say use “extensions.” The reality is that they produce completely different code, and neither of them is actually a problem, depending on which processor you’re using.


I hope this helps you look at your CSS code and write better rules. Remember what I said earlier: CSS is code, and therefore worth paying attention to, so maintain your code base carefully. If you give it more love, you will be rewarded.

aboutBelén Albeza

Belen is an engineer and game developer currently working with the Mozilla Development Consortium. She focuses on web standards, high quality code, and game development.

  • www.belenalbeza.com
  • @ladybenko

More articles by Belen Albeza…