Frank Perez

Frank Perez

Keep in touch

An experienced Web Developer with years of experience in design, programming and server administration.

Blog

Overview

© 2024 by Frank Perez.

Using Functions and Mixins with Stylus

Stylus allows you to create functions and mixins of reusable code for your stylesheets. You can also handle mathematical operations, unary operations, and more allowing you complete control over your stylesheets with ease.

Mixins are synonymous with functions. What determines when you call something a mixin or function is based on its usage. Mixins by definition are invoked as a statement, where functions are part of an expression.

Constructing A Function / Mixin

Let’s assume you’re wanting to create a function to handle rounding corners of an element. We can simply name it border-radius, to keep it in line with the actual syntax. Only now when we’d call border-radius within our code it would generate the code with support for various browsers.

Let’s create a box as our example with rounded corners.

Stylus Code

border-radius()
  -webkit-border-radius: arguments
  -moz-border-radius: arguments
  border-radius: arguments

.box
  width: 100px
  height: 100px
  background-color: blue
  border-radius(10px)

Stylus Output

.box {
  width: 100px;
  height: 100px;
  background-color: #00f;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
}

Notice how the output now contains the 3 lines required to generate rounded corners for multiple browser support. Another thing to note is that we were able to pass the value of 10px to each line by calling the arguments keyword. This will allow us to reuse the function throughout our entire code base.

We can even take this a step further, and make the function a little more transparent by losing the parenthesis altogether. This is the beauty of using mixins, as it allows you to transparently add support for various browsers while keeping the syntax the same.

Stylus Code

border-radius()
  -webkit-border-radius: arguments
  -moz-border-radius: arguments
  border-radius: arguments

.box {
  width: 100px
  height: 100px
  background-color: blue
  border-radius: 10px
}

Stylus Output

.box {
  width: 100px;
  height: 100px;
  background-color: #00f;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
}

Notice we still get the same result, and it’s a little more natural writing it this way.

Let’s look at another example of creating a mixin where we alternate the background colors of our rows of a table.

Stylus Code

stripeRows(even = #eeeeee, odd = #dddddd)
  tr
    background-color: odd

    &:nth-child(even)
      background-color: even

table
  stripeRows()

Stylus Output

table tr {
  background-color: #ddd;
}
table tr:nth-child(even) {
  background-color: #eee;
}

Argument Defaults

You can also set default values for your arguments if one is not provided. Let’s look at the border-radius example, and add a sensible default if a value is not provided.

Stylus Code

border-radius(radius = 10px)
  -webkit-border-radius: radius
  -moz-border-radius: radius
  border-radius: radius

.box
  width: 100px
  height: 100px
  background-color: blue
  border-radius()

Notice that we set the the default value to 10px, so if no value is set the border radius would be set to 10px by default.

Named Parameters

You can also pass named parameters to your function as well. The benefit to this approach is if you have more then 1 parameter to your function you’re not required to remember the order of how the arguments should be passed.

Stylus Code

.box
  width: 100px
  height: 100px
  background-color: blue
  border-radius(radius: 10px)

Multiple Return Values

Interestingly enough, a function can also return multiple values as well. Let’s look at an example where we create a perfect square box.

Stylus Code

squareBox(x, color = blue)
  dimensions = squareCoordinates(x)
  box(dimensions[0], dimensions[1], color)

squareCoordinates(x)
  return x x

box(x, y, color = blue)
  width: x
  height: y
  background-color: color

.box
  squareBox(150px)

Stylus Output

.box {
  width: 150px;
  height: 150px;
  background-color: #00f;
}

You’ll notice that now we only have to call the function squareBox() and pass the size, and the rest of the box code will be generated for us.

Conditionals

Like other programming languages, we can also take advantage of conditionals. This can be useful to us in cases where we’d need some set of styles applied in certain cases and not others.

Let’s look at an example where if someone creates a box which is not a perfect square we add some extra margin to the needed side to make it square.

Stylus Code

box(x, y, color = blue)
  width: x
  height: y
  background-color: blue
  if(x > y)
    margin: ((@width - y) / 2) 0
  else
    margin: 0 ((@height - x) / 2)

.box
  box(50px, 100px)
  float: left

Stylus Output

.box {
  width: 50px;
  height: 100px;
  background-color: #00f;
  margin: 0 25px;
  float: left;
}

Anonymous Functions

You can also create anonymous functions using the @(){} syntax. The documentation provides a good example using a sort function here.

Arguments

The arguments keyword is available within each function block. It will contain the list of all arguments passed to the function.

In one of our previous examples of the border-radius, you found that we were using the keyword arguments instead of a variable name. This allowed us to pass any parameters/arguments we need to our function without manually specifying each allowed argument .

Stylus Code

border-radius()
  -webkit-border-radius: arguments
  -moz-border-radius: arguments
  border-radius: arguments

.box {
  width: 100px
  height: 100px
  border-radius(10px)
}

Stylus Output

.box {
  width: 100px;
  height: 100px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
}