Generating CSS With Stylish
Writing CSS can be a frustrating experience. Browser incompatibilities bedevil one’s every move; the speed with which improvements in the specification are actually implemented by vendors is glacial; and everywhere, one is forced to copy and paste code with minor variations, simply to work around some fundamental limitations in the language.
There seems to be little that developers can do to rectify the first two problems, but solving the third is within our grasp. Stylish is my attempt at doing so. It’s a small Ruby library which allows one to generate stylesheets programmatically, via the use of a simple but powerful DSL.
When attempting to reduce code duplication (and the transcription errors which accompany it), two major weaknesses in CSS spring immediately to mind: the lack of variables, and the lack of iteration. Consider the common use case of developing minor variations on a site’s style:
.autumn a {color:#90211c;}
.autumn a:hover {color:#bb5f1b;}
.winter a {color:#16335f;}
.winter a:hover {color:#5a9bce;}
.spring a {color:#448e1c;}
.spring a:hover {color:#6bcf35;}
.summer a {color:#c8ad1a;}
.summer a:hover {color:#d3482c;}
Here we have four groups of rules, each with the same pattern but slightly different values for their selectors and declaration values. Using Stylish, we can write a small snippet of code to generate the correct structure, giving us a template which we can pass variables into.
style = Stylish.generate do
rule :season do
a :color => :link
rule "a:hover", :color => :hover
end
end
Now we need to map those variables–:season, :link and :hover–to some actual values. Note that variables are only supported for selector and declaration values, not declaration properties.
seasons = [{:season => ".autumn", :link => "90211c", :hover => "bb5f1b"},
{:season => ".winter", :link => "16335f", :hover => "5a9bce"},
{:season => ".spring", :link => "448e1c", :hover => "6bcf35"},
{:season => ".summer", :link => "c8ad1a", :hover => "d3482c"}]
Finally, we can generate some CSS code. Calling to the to_s method on the style object serialises the structure we initially created, filling in the variables with concrete values from our mappings.
seasons.each do |season|
puts style.to_s(season)
end
The entire script is available; a couple of other examples can be found in the project’s example/ directory. Installing Stylish, assuming that you have Ruby and Rubygems, is as simple as typing the following command into your terminal.
sudo gem install ionfish-stylish -s http://gems.github.com
I’ve published a fairly comprehensive introductory tutorial on the Stylish documentation site. It eases the reader into developing with Stylish through a series of code examples which demonstrate all the main features of the stylesheet generator.