Back to Blog

12 Best Practices for CSS Development

09
Aug
2021
Development
CSS Development Tips and Best Practices

CSS (Cascading Style Sheets) is the language that defines a website’s presentation. Mostly, it's easy to learn at first. But writing it the right way is another skill. And one that's essential in professional web development.

There are several ways to achieve goals in CSS, some of which are better than others. For example, many team members can access and change CSS files in a software company.

Code can break if everyone involved is not following the same standards. This lack of protocol will most likely lead to rewriting it. Thus, developers must stay in touch with best practices to be on the same page as their teammates!

So, let's take a look at our team's 12 tips and best practices regarding CSS.

1. CSS Readability

Write with many lines and give a line to every property. Most people prefer multi-line CSS. Yet, there are a few cases when single-line CSS can be more readable. Multi-line CSS makes it easier to find specific properties, like in the example below.

A. Single Line
.class {color: #fff; text-align: center;}
};
B. Multi Line
.class {
 color: #fff;
 text-align: center;
};

2. CSS Resets

A reset is vital to deal with browser inconsistencies. Further, it helps avoid unpleasant surprises. It can be anything: from a few lines of code on top of your stylesheet to an entire library of styles, like sanitize.css. With a CSS framework, it’s not necessary to reset. Also, strategies for resets vary. Let's see it below!

Universal
* { padding: 0; }
Seemingly the easiest, but also with unintended consequences. If padding is set to zero for everything, this includes elements like buttons where padding is expected.
Eric Meyer's
html, body, div, h1, blockquote. * { padding: 0; }
A famous reset template that is free to copy and modify. This reset sets a baseline for select elements where it’s most useful.
Browser Correction
display: block;
A reset that targets compatibility issues on browsers.
Opinionated
box-sizing: border-box;
Certain elements are given a default style (such as a specific font or behavior), rather than merely zeroed out.

3. CSS Patterns

You should consistently organize your stylesheets. Following organizational patterns allow everyone to find sections of code. We use this index:

  • Reset.
  • Font-face (when needed).
  • Layout styles.
  • Global styles.
  • Page sections, in the order in which they appear.
    (header, nav, home, internal pages, footer).
  • Media Queries.

4. CSS Properties

Save time and make your CSS more readable by using shorthand properties. These allow you to condense many properties into one convenient property. You can use shorthand properties for time-saving and make your CSS more readable.

Even so, it’s important to know how they work before using them. Not defined values in the shorthand property will be set to their default. Thus, unwittingly, you can override defined styles. In the following code, the background color will be transparent: the default value.

body {
 background-color: #f4f4f4;
 background: no-repeat url("img_cat.gif") fixed center;
}

5. CSS Specificity

Use the smallest amount of needed selectors to apply a property. In the spirit of keeping code as clean as possible, whenever possible, don’t be more specific than .class. In some cases, it may be necessary to use more than .class, especially when applying .ID. 

ID trump class in the specificity hierarchy: ID > Class > Element. Yet, a selector like .div.class is even more specific than an ID. In this code, font-size: 12px takes precedence, no matter its order. But, in the next line, font-size: 14px wins, because div.fake is more specific.

#real{
 font-size: 12px;
}
.fake{
 font-size: 14px;
}
div{
 font-size: 18px;
}

6. CSS Classes

You should pay attention to correctly formatting classes. Use the – separator when writing classes! Don’t use camelCase or underscores to name them.

Correct: first-section
Incorrect: firstSection, first_section

7. CSS Selectors and Properties

Space out multiple selectors and long properties. Make stylesheet reading easier with line spaces!

h1,
h2,
h3,
 background:
  url('a long URL')
  no-repeat
  left bottom
 other-property:...;
}

8. CSS !important

Property !important tends to be the last resource. Moreover, it only applies when specificity doesn’t work. This often happens with inline styles or styles injected with JavaScript.

9. CSS Calc ( )

You’ve got a friend in Calc()! It allows you to use operators for properties with units of measure. For instance, height, width, font size, border, etc. The right way of writing this is property:(x + x). All operators can be used, and different units of measure can be used in the same operation. For example:

div {
 height: calc(100% - 80px)
}

10. CSS Units of Measure

Get your units of measure clear! Fonts can get various measure types, like EM, PX, PT, REM, or %. Within those, the most used are PX and EM.

  • EM:  This scalable unit equals the parent document’s font size. Imagine a <div> with font-size: 16px;. In this case, 1em=16px, 2em=32px, and so forth, within that div and its child elements.‍
  • REM:  Also scalable but related to the root HTML element. 16px is its default in most browsers.‍
  • PX:  Screen’s pixels, or the minor division the resolution allows.‍
  • PT:  1 PT equals 1/72 of an inch. This is not a commonly used measure unit.‍
  • %:  Percentage of the parent element’s font size.

EM’s advantage is its scalability, which is beneficial for media queries. Every font declared in EM will vary along with the main one. By contrast, PX maintains a set size. With this logic, EM and REM can also be used for margins, paddings, etc.

1EM = the font-size of the parent element.
1REM = the font-size of the root <html> element. By default, 100%=16px.

If a <divi> has font-size:18px;, that would be the value for its children. But, if not modified, 1rem would remain 16px. To spice things up, we can also use VH and VW. 1VH = 1% height of the viewport

These come useful when we need that an element remains relative to screen size. You could use height:100%, but if not defined, the element doesn’t know what 100% of its height is. In this scenario, VH comes to the rescue because it’s always using the viewport as a reference.

11. CSS Box-Sizing

By default, to determine the width, CSS adds element values to determine the width. By default, these values exclude the margins. For example:

div {
 width: 100px;
 padding: 20px;
 border: 1px solid black;
 margin: 20px;
}

We get a box 42px tall and 142px wide, with 20px margins on all sides.

But, wait — if height is not defined, where is 42px coming from?  This happens because CSS adds all the values inside the element. So, while the default height is 0px, 20px of top and bottom padding, with a 1px border on each side, is 42px.

The same logic applies on width: 100px, with 20px left and right padding, and 1px border on each size, which equals 142px.

Use box-sizing: border-box to make sizing easier to manage. This allows the element’s width to be directly declared (100px in this case). All the other values will be placed inside the box.

In this case, using box-sizing: border-box, we’ll get a 100px box. Further, with border and padding contained within that measure.

12. CSS NTH Children and Types

You can target the children of certain elements, within groups of siblings, with :Nth-child() and :nth-of-type(). For example, in a <ul> we can give styles to some of the <li> elements and not others.

And, if we have a <div> encompassing different aspects, we can set X element in X position to a different style.

You can target the children of certain elements with :Nth-child() and :nth-of-type(). These categories apply to groups of siblings. For example, in a <ul> we can give styles to some of the <li> elements and not others.

If we have a <div> encompassing different elements, we can set X element in X positions.

A. Selects every fourth element among a group of siblings
 :nth-child(4n) {
   color: lime;
 }
B. Selects every fourth among a group of siblings
 :p:nth-of-type(4n) {
   color: lime;
 }

Both cases permit operations. For instance, :nth-child(2n+1) will select the first, third and fifth, and so forth. That’s because it multiplies 2 (and any value), starting with zero, adding 1.

It’s possible to “attack” only pairs or non-pairs – :nth-of-type(odd) or :nth-child(even)–. You can also apply it only to the first or last element, with :first-child or :last-of-type.

Even more, you can count back and forth when using dynamic content. Also, if you want to style on the next-to-last element, third-to-last, etc.

This may be complicated with a (xn+y) operation. Fortunately, :nth-last-of-type() and :nth-last-child() exist to make this easier. Take this as an example:

A. :nth-last-child(7)
 Represents the 7th element, counting from the last element.
B. :nth-last-child(2n)
 Goes from 2 by 2 starting from the last element. This would be the same as using "even".
C. :nth-last-child(3n + 1)
 Starts from the last element (3x0 = 0 +1 = 1) and goes to the 4th.

We hope these CSS tips and practices help you improve your styling game! You can dive further into CSS with our 15 Key Advanced CSS Best Practices.