Getting To Know Stylus

Share this article

If you are part of the front-end scene, you might have heard of Stylus, the distant cousin from Sass that nobody knows very well. Like Sass, Stylus is a CSS preprocessor which is written in Node.js. According to its GitHub repository, it describes itself as:

[…] a revolutionary new language, providing an efficient, dynamic, and expressive way to generate CSS.

Okay, revolutionary might be a bit exaggerated. But everything else is true.

What, another one!?

Kind of. But Stylus isn’t brand new. It has been around since the beginning of 2011, but I see it as having quite a discrete community. By the way, did you know the latest Mozilla Developer Network redesign has been made with Stylus? David Walsh, who’s been involved in the project, also wrote about how to get started with Stylus.

So what are the advantages of Stylus over Sass? Well, it is built in Node.js which sounds like a plus side to me. And while it is perfectly fine to use Sass in a Node workflow thanks to Node-Sass wrapper for LibSass, it does not make LibSass written in Node for all that.

Also Stylus has an extremely permissive syntax, which can be a good or a bad thing depending on your project, your team and your tendency to stick to strict coding guidelines. I think a permissive syntax should be fine as long as you do not involve too much logic in the stylesheet, and lint the code before committing.

All in all, Stylus and Sass both support pretty much the same things; you can have a look at the full list of Stylus features but don’t expect anything ground breaking (although there are some neat features). Stylus also supports multiple syntaxes although the line is much more blurry than Sass: you can write your styles pretty much how you want (indented, CSS-style) and you can mix and match within the same stylesheet (the parser for this must have been fun to write).

So what do you think? Want to give it a try?

Getting started

As stated before, Stylus is written in Node.js so we can install it like any other npm package:

$ npm install stylus -g

From there, either you can plug it into your Node workflow using the JavaScript API, or you can use the command line executable to compile your stylesheets. For the sake of some simplicity, we will use the stylus command line tool but feel free to tackle it from a Node script, Gulp or Grunt.

stylus ./stylesheets/ --out ./public/css

The previous command tells stylus to compile all Stylus stylesheets (.styl) from the stylesheets folder and to generate them in public/css folder. Of course, you can also watch the directory for changes:

stylus --watch ./stylesheets/ --out ./public/css

Writing Stylus styles

If you are just getting started and don’t want to feel overwhelmed with a new syntax, know that you can write plain CSS in a .styl file. Since Stylus does support the standard CSS syntax, it is perfectly fine to start with CSS code only to enhance it slowly.

Basic syntax

Regarding the syntax itself, almost everything is optional. Braces: why bother? Semi-colons: come on! Colons: ditch ’em too. Parentheses: please. The following is perfectly valid Stylus code:

.foo
.bar
  color tomato
  background deepskyblue

Kind of disturbing at first but we could get used to it, especially when there are syntax highlighters available. As you can probably guess, the previous code compiles into:

.foo, .bar {
  color: tomato;
  background: deepskyblue;
}

Variables

The most used feature from CSS preprocessors has to be the ability to define variables. It’s not surprise that Stylus offers it as well. Although contrary to Sass, they are declared with an equal sign (=) rather than a colon (:). Also, the leading dollar sign ($) is optional and can be safely omitted.

// Defining a `text-font-stack` variable
text-font-stack = 'Helvetica', 'Arial', sans-serif;

// Using it as part of the `font` property
body
  font 125% / 1.5 text-font-stack

Now there is something that Stylus does which Sass or any other preprocessor does not: property value look-up. Let’s say you want to apply a negative left margin of half the width; in Sass you’d have to store the width in a variable, but not in Stylus:

.foo
  width 400px
  position absolute
  left 50%
  margin-left (@width / 2)

By using @width, we tell Stylus to fetch the value of the width property of the current block, treating it as a variable. Pretty neat! Another interesting use-case for this is to conditionally output a property depending on whether or not it has already been defined:

.foo
  // ... other styles
  z-index: 1 unless @z-index

In this case, z-index will be set to 1 unless .foo already has a value assigned for the z-index property. Couple this with mixins and you really have something.

Mixins

Speaking of which, let’s define a mixin since it’s probably one of the most popular features of Sass! A mixin in Stylus needs no specific keyword; it is a mixin as long as it has the parentheses (empty or not) at the end of its name.

size(width, height = width)
  width width
  height height

Along the same lines, including a mixin needs no specific syntax like @include or +:

.foo
  size(100px)

You can even drop the parentheses if you feel so, in which case it looks like you use a completely standard (yet not) CSS property. This mechanism is referred to as transparent mixins as their inclusions are invisible.

.foo
  size 100px

That might look an unnecessary trick at first glance, but this feature actually allows authors to extend the default CSS syntax if you think about it. Consider the following overflow mixin:

overflow(value)
  if value == ellipsis
    white-space nowrap
    overflow hidden
    text-overflow ellipsis
  else
    overflow: value

If the given value is ellipsis, it prints the well-known declaration triplet needed to have a one-line ellipsis overflow. Else, it prints the given value. Here is how you’d use it:

.foo
  overflow ellipsis

And it will yield:

.foo {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

You gotta admit, that’s a pretty cool trick. While it might be confusing (and possibly dangerous), being able to extend the standard CSS properties with extra values is actually an interesting concept.

If you want to pass some content to a mixin, in a @content fashion, it is possible through a {block} variable. During the inclusion, you only have to prefix the mixin name with + to pass it extra content.

has-js()
  html.js &
    {block}

.foo
  +has-js()
    color red

This code will compile to:

html.js .foo {
  color: #f00;
}

Last very interesting feature of Stylus mixins: they always have a arguments local variable containing all arguments (if any) passed to the mixin when included. This variable can be manipulated and treated as an array, for instance to fetch values at specific indexes using [..] like in JavaScript.

Final thoughts

Going through all features and syntax tricks from Stylus would be too long and I think we already had a decent introduction, enough to get started at least!

As you can see, Stylus is extremely permissive. Of all existing tools to help writing CSS, Stylus is definitely the one bringing CSS the closest to a real programming language.

Note that Stylus also has its own framework in the same way that Sass has Compass, and it’s called Nib. Nib is a toolbox providing extra helpers and cross-browsers support mixins for Stylus.

Some people might like it, some people might not. My advice would be to be very rigorous with the syntax though. Dealing with such a tolerant syntax might not always be such a bliss. In any case, it’s nice to see some decent concurrence to Sass.

Frequently Asked Questions (FAQs) about Stylus

What are the key differences between Stylus and other CSS preprocessors?

Stylus is a dynamic stylesheet language that is both powerful and flexible. Unlike other CSS preprocessors like Sass and Less, Stylus allows for optional use of brackets, colons, and semicolons, making it more flexible and less strict. It also supports both an indented syntax and regular CSS style, giving developers more freedom in how they write their code. Additionally, Stylus supports transparent mixins, which means you can call mixins without using any special syntax.

How do I install Stylus?

Stylus can be installed using Node.js and npm (Node Package Manager). First, you need to install Node.js and npm on your computer. Once installed, you can install Stylus globally by running the command npm install stylus -g in your terminal or command prompt. This will allow you to use Stylus from any directory on your computer.

How do I compile Stylus to CSS?

After writing your Stylus code, you can compile it to CSS using the stylus command in your terminal or command prompt. For example, if your Stylus file is named style.styl, you would run the command stylus -c style.styl. This will create a CSS file named style.css in the same directory.

Can I use variables in Stylus?

Yes, Stylus supports the use of variables. You can define a variable by assigning a value to a name. For example, font-size = 14px. You can then use this variable elsewhere in your code by referencing its name, like so: p { font-size: font-size; }.

Does Stylus support functions and mixins?

Yes, Stylus supports both functions and mixins. Functions in Stylus are defined using the def keyword and can be used to perform calculations or manipulate values. Mixins, on the other hand, are reusable blocks of code that can be included in other rulesets.

How do I use conditional statements in Stylus?

Stylus supports conditional statements using the if, else if, and else keywords. These can be used to apply different styles based on certain conditions. For example, you could use a conditional statement to apply different font sizes based on the screen size.

Can I import other Stylus files?

Yes, Stylus allows you to import other Stylus files using the @import directive. This can be useful for organizing your code into separate files and reusing code across multiple stylesheets.

Does Stylus support loops?

Yes, Stylus supports both for and while loops. These can be used to generate repetitive CSS rules or to iterate over lists and arrays.

Can I use Stylus with Node.js?

Yes, Stylus can be used with Node.js. In fact, Stylus is built on Node.js and can be installed using npm, the Node Package Manager. You can also use Stylus with Express, a popular web application framework for Node.js.

How do I debug Stylus code?

Stylus provides a --debug flag that can be used to output debugging information. This can be helpful for tracking down errors or understanding how your code is being processed. Additionally, you can use the inspect() function in Stylus to output the value of a variable or expression.

Kitty GiraudelKitty Giraudel
View Author

Non-binary trans accessibility & diversity advocate, frontend developer, author. Real life cat. She/they.

AdvancedCSSCSS Preprocessingcss preprocessornodenode.jspreprocessorStylus
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week