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:

tim-email

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!