Heads up! This blog post hasn't been updated in over 2 years. CodePen is an ever changing place, so if this post references features, you're probably better off checking the docs. Get in touch with support if you have further questions.
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.
The Parameters
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.
require './lib/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[0]
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.
Results
It’s a tiny addition, but it’s made for some really amazing Pens.
See the Pen CSS Particle Explosion by turusuke (@turusuke) on CodePen
See the Pen Shooting Rings by Oliver Knoblich (@oknoblich) on CodePen
See the Pen Fly-in letters – no js by Mark Lee (@leemark) on CodePen
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!