CSS is simple to learn and straightforward to write, it’s fast to start but slow to scale. Based on how CSS works, we can’t expect it to be developed into a powerful programming language but to build supporting tools around it.
Over the years, community has built a great ecosystem around CSS to supercharge its capability, from preprocessors like Sass and Less to methodologies like BEM and Atomic CSS, to more recent developments like CSS-in-JS.
This post will discuss a bit about three popular pure preprocessors - Sass, Less, Stylus - and a special JavaScript tool PostCSS.
CSS is primitive and incomplete. Building a function, reusing a definition or inheritance are hard to achieve. For bigger projects, or complex systems, maintenance is a very big problem. This is where a preprocessor can help.
A CSS preprocessor is a program that lets you generate CSS from the its own unique syntax. To use a CSS preprocessor, you must install a CSS compiler on your web server.
There are many CSS preprocessors to choose from, however most CSS preprocessors will add some features that don’t exist in pure CSS, such as mixin, nesting selector, inheritance selector, and so on.
Features | Sass | Less | Stylus |
---|---|---|---|
Variables | Yes | Yes | Yes |
Nesting | Yes | Yes | Yes |
Mixins | Yes | Yes | Yes |
Extends | Yes | Yes | Yes |
Functions | Yes | Yes | Yes |
If/else | Yes | Mixins | Yes |
Loops | Yes | Mixins | Yes |
Math | Yes | Yes | Yes |
Import | Yes | Yes | Yes |
Many of the features offered are incredibly similar across preprocessors, with only slight variances in syntax. Thus, you can choose pretty much any you wish, and will be able to achieve the same things. Using preprocessors brings you many benefits to boost your productivity:
Sass is the most mature, stable, and powerful preprocessor. It is completely compatible with all versions of CSS, very mature, feature rich, industry standard, large community, and has many frameworks built around.
Sass supports two different syntaxes. Each one can load the other, so it’s up to you and your team which one to choose.
.scss
, it’s a superset of CSS, which means essentially all valid CSS is valid SCSS as well. Because of its similarity to CSS, it’s the easiest syntax to get used to and the most popular.@mixin button-base() {
@include typography(button);
@include ripple-surface;
@include ripple-radius-bounded;
display: inline-flex;
position: relative;
height: $button-height;
border: none;
vertical-align: middle;
&:hover {
cursor: pointer;
}
&:disabled {
color: $mdc-button-disabled-ink-color;
cursor: default;
pointer-events: none;
}
}
.sass
. The indented syntax supports all the same features as SCSS, but it uses indentation instead of curly braces and semicolons to describe the format of the document.@mixin button-base()
@include typography(button)
@include ripple-surface
@include ripple-radius-bounded
display: inline-flex
position: relative
height: $button-height
border: none
vertical-align: middle
&:hover
cursor: pointer
&:disabled
color: $mdc-button-disabled-ink-color
cursor: default
pointer-events: none
Less (Leaner Style Sheets) is a backwards-compatible language extension for CSS. Because Less looks just like CSS, learning it is a breeze. Less only makes a few convenient additions to the CSS language, which is one of the reasons it can be learned so quickly.
@the-border: 1px;
@base-color: #111;
@red: #842210;
#concrete_header {
color: @base-color * 3;
border-left: @the-border;
border-right: @the-border * 3;
}
#concrete_footer {
color: @base-color + #003300;
}
Stylus is a preprocessor developed by Holowaychuk and influenced by Sass and Less. It offers a wider range of features, a super-fast Node.js system under the hood, and gives users the most freedom in how they write their CSS.
border-radius()
-webkit-border-radius: arguments
-moz-border-radius: arguments
border-radius: arguments
body
font: 12px Helvetica, Arial, sans-serif
a.button
border-radius(5px)
PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.
PostCSS is not a pure preprocessor
but you can use it that way if you wanted to by using along with plugins like postcss-sass
, postcss-scss
or postcss-less
. After preprocessing you can also use PostCSS processing with other plugins.
PostCSS is a Node module that parses CSS into an abstract syntax tree; passes that AST through any number of plugin functions; and then converts that AST back into a string, which you can output to a file. Each function the AST passes through may or may not transform it; sourcemaps will be generated to keep track of any changes.
PostCSS is a low-level module that facilitates the creation of other tools; and there are no limits on what those higher-level tools (the plugins) might do.
Each plugin is only part of your build process because you put it there. If a plugin displeases you, remove it. Nobody is going to stop you.
The most compelling thing about PostCSS is it is not restricted to any one type of functionality; it represents a completely customizable and configurable set of functionality that is potentially unlimited.
The ecosystem of PostCSS plugins has been developing in an incredible speed. You can find all at this catalog of PostCSS plugins:
postcss-use
, postcss-modules
, postcss-initial
.autoprefixer
, postcss-preset-env
.precss
, postcss-sorting
, postcss-utilities
.postcss-assets
, postcss-sprites
, postcss-inline-svg
.stylelint
, stylefmt
, colorguard
.sugarss
, posscss-sass
, postcss-scss
.postcss-rtl
, cssnano
, lost
.PostCSS is well supported by all kinds of bundlers and task runners like: Parcel, Webpack, Gulp, Grunt, Rollup, etc.
// Simple setup with Gulp task runner
gulp.task(css, () => {
const postcss = require('gulp-postcss')
const sourcemaps = require('gulp-sourcemaps')
return gulp
.src('src/**/*.css')
.pipe(sourcemaps.init())
.pipe(postcss([require('precss'), require('autoprefixer')]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('build/'))
})
Whether you like preprocessors or not, they were created for a reason of making your life easier in some ways. By far Sass is the most adopted preprocessor out there in tech industry, knowing it thoroughly will give you a big advantage as frontend developer.
CSS is simple to learn and straightforward to write, it’s fast to start but slow to scale, you probably don’t know that you’re already using CSS preprocessors cooked in built tools.
With the rise of PostCSS, my decisions have been shifted from whether to use CSS preprocessors or not to what problems I want to solve with CSS.