On CodePen, Sass is the most popular CSS preprocessor by a large margin. It makes up 69% of all preprocessor use. Although already powerful, Sass can be extended. Additional functions can be added to what it what it can already do. After all, it's an open source Ruby project!
Tim Holman sent us an idea:
We agree Tim! The
random() function to Sass makes for some really interesting Pens. You may have noticed we shipped this feature already.
Here's how we did it.
Our goal was to make
random() as simple as possible. You either use it with zero arguments and get a number between 0-100, or one argument (e.g.
random(200)) and get a number between 0 and that number.
We also figured that, heck, since Sass already has a bunch of math functions, if you need to alter the random number that you get (say to have negative values) you could just use those (e.g.
random(200) - 100).
The Preprocessor Service / Extending Sass
Sass and all the other Preprocessors on CodePen run as a separate service aptly named the Preprocessor Service. Like Sass itself, our preprocessor service is written in Ruby.
require 'sass' # all our other Ruby-based preprocessors class PreProcessorService end
After we require 'sass', we require an additional Ruby file of our own making where we can extend Sass.
Since the Sass module exists now, we can extend it in that new file. We can add our new function by extending the Sass::Script::Functions module. Below is the actual function we added to Sass.
module Sass::Script::Functions def random(*args) case args.size when 1 limit = args else limit = Sass::Script::Number.new(100) end assert_type limit, :Number, :limit random_number = rand(limit.value) return Sass::Script::Number.new(random_number) end end
Our function looks for an argument and if it doesn't find one creates a Sass::Script::Number object. This is the same type of number we must return to Sass for processing.
We make use of the actual Ruby random number generator function
rand(), passing it the limit parameter passed to the random() function.
Finally we return Sass::Script::Number type object Sass can use internally.
It's a tiny addition, but it's made for some really amazing Pens.
See more in this collection.
One little tricky bit specific to CodePen: we had to carefully and specifically document that if you use this function and export your Pen, you run the risk of the next Sass compiler you use not recognizing it. Good thing we have this blog post to explain!