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;
}