Jump to main content
Menu

Preprocessors and Custom Properties (Variables)

CSS Preprocessors

  • The idea behind a CSS preprocessor is to write your CSS in a different way, following a different syntax, then run a compiler that produces the CSS that you otherwise would have written by hand.
  • If that sounds bizarre to you, that's a reasonable reaction.
  • The Web languages that we use (HTML, CSS, and JavaScript) do not need us to run a compiler on them before putting the code into the browser. Browsers have a rendering engine (HTML), parser (CSS), and interpreter (JavaScript) already built in. We write our code, and the browser does the rest.
  • If you're approaching web development from a different medium, such as desktop Windows / OS X development, then compiling your code is standard practice. In those cases, what you write is changed into machine code, or something equivalent, that can run very fast.
  • In this particular case, we're transforming what you write in the preprocessor into the final CSS output.
  • Ideally, you're authoring your stylesheets in an application / environment that does the real-time compiling as you save changes to the file(s).

Pros and Cons of Preprocessors

  • A positive perspective on preprocessors is that they allow us to manage an increasingly large CSS code base (perhaps thousands of lines of CSS) and make far-ranging changes rapidly.
  • A negative perspective on preprocessors is that they are adding complexity to our process, by having an extra compilation step involved. It is also possible to end up with a lot of files when using a preprocessor, as each file could contain just a small part of the overall stylesheet that gets generated.
  • How does one balance these two perspectives? If you're dealing with an enormous website or application that has a lot of CSS, and you're using tools that are set up for preprocessing, then perhaps a preprocessor makes sense. If you're building a smaller website that is unlikely to need rapid and massive changes, then skipping these makes sense.

Preprocessor Options

  • The two preprocessors you will encounter most often are SASS and LESS.
  • SASS is more popular, so we will focus on that.
  • Reading through the SASS guide is recommended.
  • You will need a compiler, so that you can output the CSS files as you work. Koala is a good option, because it is an application you can run on your computer. Working with SASS on the command line is also an option.
  • There are two syntax options with SASS. The one that looks the most like regular CSS is called SCSS, and you end your files in .scss. The other syntax, which removes curly braces and relies on spacing/indenting (very similar to the Python programming language) is called Sass, and those files end in .sass. As you review the SASS guide you will see that the examples let you toggle between the syntax choices. Both syntaxes produce the same output.
  • You will also see the acronym DRY when you read through the guide. That means "Don't Repeat Yourself". In this context, it means do not write the same CSS multiple times. Write it once and then have that code output numerous places in the generated CSS.

CSS Custom Properties (Variables)

  • CSS custom properties, often referred to as CSS variables, bring some of the conveniences of the preprocessors into the language.
  • One of the most important preprocessor features is the use of variables that you could define once and then output throughout the code. CSS variables provide this capability, and add some additional value beyond that.
  • The major drawback of variables in a preprocessor is that they can only be updated prior to compiling the CSS. Once your CSS has been generated, there's no way to change those values on the fly, because they are no longer variables!
  • In contrast, if you use a CSS variable, you can update that variable via JavaScript and everywhere else in the CSS that uses it will update as well.
  • To define a custom property in CSS, you preface it with -- and avoid spaces in the property name, such as:
    /* root is the parent element, in our case html 
       we often use this element to define our properties / variables
    */
    :root {
      --primary-bg-color: #eee;
      --primary-txt-color: #000; 
    }
    
  • These custom properties are then called using var(), such as:
    :root {
      --primary-bg-color: #eee;
      --primary-txt-color: #000;
    }
    
    .column {
      background: var(--primary-bg-color);
      color: var(--primary-txt-color);
    }
    
  • It is possible to define custom properties at a lower level than :root:

    See the Pen CSS Custom Properties (Variables) by Jason Withrow (@jwithrow) on CodePen.

Best Practices for CSS Custom Properties / Variables

  • Create variable names that still make sense even as their values change.

    Create --primary-bg-color and --secondary-bg-color rather than --gray-bg-color and --purple-bg-color, because those last two don't make sense when you change the layout / theming and switch them to different color values.

    You shouldn't be renaming your custom properties over time. Their values change, but the custom property name should not.

  • Use custom properties for the values that get re-used frequently.

    Font families, text colors, background colors, text sizes, etc. Ask yourself:

    • What values are being re-used?
    • If a redesign needed to occur, what values should be set up for quick updates?
  • :root gives the most flexibility when defining the custom properties.

    Following this practice, the custom properties can be used anywhere in your CSS, because everything being styled via CSS is within the root element (the html tag). Yes, there is inheritance and specificity, just like any CSS rule being inherited and resolving specificity concerns via the cascade.

    The goal is to write the value just once, so having numerous cases where the value is redefined for a particular subset of the code seems counter-productive.