logo-footer

12 CSS Styling Tips and Best Practices

CSS, (Cascading Style Sheets) the language that defines a website’s presentation, is easy enough to learn at first.

However, writing it the right way is another skill entirely, one that’s essential in professional web development.

There are several ways to achieve goals in CSS, with some of them better than others. For example, in a software company, multiple team members can access and modify CSS files. Code can break if everyone involved is not following the same standards, which will lead to rewriting it. Therefore, developers must stay in touch with best practices or, at least, be on the same page as their teammates.

Our team’s tips and best practices for writing CSS

01. Make it readable

Write with multiple lines and give a line to every property. Most people prefer multi-line CSS, although 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.

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

02. Use a reset

A reset is vital to deal with browser inconsistencies and to avoid unpleasant surprises. It can be anything: from a few lines of code on top of your stylesheet, to a full library of styles, like sanitize.css.

Note: with a CSS framework, it’s not necessary to reset. Strategies of reset vary.

The strategy of a reset varies. The main types are summarized in the table below:

null

03. Follow an Organizational Pattern

Stylesheets must be organized in a consistent way that allows everyone to easily 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.

04. Use shorthand properties

Save time and make your CSS more readable by using shorthand properties. These allow you to condense multiple properties into one convenient property. You can use shorthand properties to time-saving and make your CSS more readable. Nevertheless, it’s important to know how they work before using them. Unwittingly, you can override defined styles, since not defined values in the shorthand property will be set to their default.

For instance, in the following code, the resulting background color will be transparent: the default value. Mozilla’s web docs are a useful reference for shorthand properties.

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

05. Go easy on specificity

Use the minimum 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, specially 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;
    }

06. Format Classes Correctly

Use the – separator when writing classes. Don’t use camelCase or _.

Correct: first-section

Incorrect: firstSection, first_section

07. Space out multiple selectors and long properties

Make stylesheet reading easier with line spaces. Like this:

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

08. Respect the awesome power of !important

Property !important is a last resource that only applies when specificity doesn’t work. This often happens with inline styles, or styles injected with JavaScript

09. Use Calc()

You’ve got a friend in Calc()! It allows you to use operators for properties with units of measure, such as height, width, font size, border, etc.

The right way of writing this is property:(x + x). All types of operators can be used, as well as different units of measure in the same operation.

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

10. Know your units of measure

Fonts can get a variety of measure types, like EM, PX, PT, REM, or %. Most used are PX and EM.
  • EM: This scalable unit is equivalent to the parent document’ 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 smallest division the resolution allows.
  • PT: 1 PT equals to 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, especially useful 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 element. By default, 100%=16px.

If a <div> 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.
1VW = 1% width of the viewport.

These come especially 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 is 100% of its height. In this scenario, VH comes to the rescue, because it’s always using the viewport as reference.

11. Set Box-Sizing

By default, to determine width, CSS adds element values, excluding margins. For example:

    div{
      width: 100px;
      padding: 20px;
      border: 1px solid black;
      margin: 20px;
    }
null
Default CSS
null
We get a box 42px tall and 142px wide, with 20px margins on all sides.
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 default height is 0px, 20px of top and bottom padding, with a 1px border on each side, is 42px. Same logic applies on width: 100px, with 20px left and right padding, and 1px border on each size, 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. Using box-sizing: border-box in this case, we’ll get a 100px box, with border and padding contained within that measure.

12. NTH your 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 to others. And, if we have a <div> encompassing different elements, we can set X element in X position to a different style.

    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..

Evenmore, you can count back and forth, when using dynamic content, and want 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:

    :nth-last-child(7)
    /* Represents the 7th element,
       counting from the last 
       element. */
    
    :nth-last-child(2n)
    /* Goes from 2 by 2 starting 
       from the last element. This 
       would be the same as using 
       “even”.*/
    
    :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. If you want to get deeper in this subject, we recommend you to read our article about CSS styling in component structures.

We are ready
to make your project happen

Let’s talk