---
layout: default
title: Stylish, a CSS generator in Ruby
article_link: http://extralogical.net/2009/05/generating-css-with-stylish/
---
<p>
Stylish is a tool that lets you generate
<abbr title="Cascading Stylesheets">CSS</abbr> code with a minimum of fuss.
Its aim is to make writing certain kinds of stylesheet much simpler. Common
examples include those with a lot of duplication, or which are just
variations on the same basic structure.
</p>
<p>
The following tutorial assumes you have Ruby and RubyGems installed. Ruby
programming knowledge helps, but should not be essential.
</p>
<div class="section">
<h1>Why would you want to write CSS in Ruby?</h1>
<p>
Because CSS doesn’t have loops or variables, and can be very
repetitive. Stylish allows you to eliminate a lot of redundancy in your
code. There are other reasons too, as we will see throughout this tutorial.
For a more comprehensive explication,
read <a href="{{ page.article_link }}">Generating CSS with Stylish</a>.
</p>
</div>
<div class="section">
<h1>Installing Stylish</h1>
<p>The simplest way to install Stylish is via RubyGems:</p>
<pre class="code terminal"><code>sudo gem install stylish</code></pre>
<p>
You’ll need to have the <a href="http://gemcutter.org/">Gemcutter
gem</a> installed, but Stylish has no other gem dependencies. Ruby 1.8.6
and Ruby 1.9 are both supported, but <a href="ruby19.html">using 1.9 is
recommended</a> since it makes developing with Stylish that bit more
pleasant.
</p>
</div>
<div class="section">
<h1>Creating simple stylesheets</h1>
<p>
The foundation of the stylesheet generation <abbr title="Domain-Specific
Language">DSL</abbr> is the <code>Stylish.generate</code> method. This
takes a block, and returns a <code>Stylesheet</code> object.
</p>
{% highlight ruby %}style = Stylish.generate do
# Your rules here
end{% endhighlight %}
<p>
Now to construct some rules. This is done with the <code>rule</code>
method, which must be passed one or more selectors, a hash of
declarations and/or a block.
</p>
{% highlight ruby %}style = Stylish.generate do
rule "div.section", :margin_bottom => "1em"
end{% endhighlight %}
<p>
Note that selectors are strings, and declarations are hashes where the keys
are symbols and the values are strings. The rule method can be a bit
verbose, so selectors which consist of a single <abbr title="Hypertext
Markup Language">HTML</abbr> element can be used directly as methods.
</p>
{% highlight ruby %}style = Stylish.generate do
p :line_height => 1.5
a :text_transform => "uppercase"
end{% endhighlight %}
<p>
Rules can also take a block, which creates a new selector scope. This means
that rules with repetitive CSS namespacing using descendant and child
selectors can be refactored into simple tree structures.
</p>
{% highlight ruby %}style = Stylish.generate do
rule "div.section" do
p :line_height => 1.5
a :text_transform => "uppercase"
end
end
style.to_s # => div.section p {line-height:1.5;}
# div.section a {text-transform:uppercase;}{% endhighlight %}
<p>
Once you’ve created your stylesheet object, you’ll probably
want to serialise it to a file. The <code>Stylesheet</code> class includes
a <code>print</code> method for just this eventuality.
</p>
{% highlight ruby %}style.print('my_style.css'){% endhighlight %}
</div>
<div class="section">
<h1>Using variables</h1>
<p>
Variables allow property values to be determined when the stylesheet is
serialised, rather than when it’s declared. A hash (in other words, a
symbol table) containing the variables’ names and values should be
passed to the stylesheet’s <code>to_s</code> method.
</p>
{% highlight ruby %}style = Stylish.generate do
a :color => :bright
end
style.to_s :bright => "f00" # => a {color:#f00;}
style.to_s :bright => "0f0" # => a {color:#0f0;}
style.to_s :bright => "00f" # => a {color:#00f;}{% endhighlight %}
<p>
Variables are represented by Ruby symbols, and can be used in place of
selectors as well as properties.
</p>
{% highlight ruby %}style = Stylish.generate do
rule :wrapper do
a :color => :bright
end
end
style.to_s :wrapper => "#wrapper", :bright => "f00"
# => #wrapper a {color:#f00;}{% endhighlight %}
<p>
Variables allow the same simple template to be used multiple times.
Creating different colour schemes is the classic use case, but there are
plenty of others.
</p>
</div>
<div class="section">
<h1>Compound values</h1>
<p>
Most declaration values are simple strings or numbers. Some, however, have
a more complex internal structure. The most common example is
<code>background</code> declarations.
</p>
{% highlight ruby %}style = Stylish.generate do
body :background => {:color => "fafafa", :image => "bg.png",
:repeat => "no-repeat", :position => ["50%", "10px"],
:compressed => true}
end
style.to_s
# => body {background:#fafafa url('bg.png') no-repeat 50% 10px;}
{% endhighlight %}
<p>
The <code>compressed</code> flag tells Stylish to use the shorthand form of
the various <code>background-</code> properties; omitting it will generate
the more specific longhand declarations.
</p>
{% highlight css %}body {
background-color:#fafafa;
background-image:url('bg.png');
background-repeat:no-repeat;
background-position:50% 10px;
}{% endhighlight %}
<p>
Variables will work both as a replacement for compound values, substituting
the entire hash or array when serialising the stylesheet.
</p>
{% highlight ruby %}style = Stylish.generate do
body :background => :bodybg
end
style.to_s(:bodybg => {:url => "/images/eyewatering.gif"})
# => body {background-image:url('/images/eyewatering.gif');}
{% endhighlight %}
<p>
However, they can also be used within the body of the compound value,
nested as deeply within the data structure as necessary.
</p>
{% highlight ruby %}style = Stylish.generate do
body :background => {:color => "000", :image => :fruit}
end
style.to_s({:fruit => "apple.jpg"})
# => body {background-color:#000; background-image:url('apple.jpg');}
{% endhighlight %}
<p>
Combining compound values and variables in this way can be very powerful,
as often one will only want to make minor changes between different
stylesheets, and picking out a particular value with a variable simplifies
the mappings between variables and values considerably.
</p>
</div>
<div class="section">
<h1>Multiple background images</h1>
<p>
Stylish attempts to build in forward-compatibility with powerful features
of CSS3 such as
<a href="http://www.w3.org/TR/css3-background/#layering">multiple
background images</a>. When using these features in Stylish, two simple
rules of thumb should be followed:
</p>
<ul>
<li>Singular declarations have singular names and take singular values</li>
<li>Multiple declarations have plural names and take arrays of values</li>
</ul>
<p>
To illustrate this, let’s look at two different background
declarations.
</p>
{% highlight ruby %}style = Stylish.generate do
body :background => {:image => "single.png"}
rule ".wrap", :background => {:images => ["first.png", "second.png"]}
end
style.to_s # => body {background-image:url('single.png');}
# .wrap {background-image:url('first.png'), url('second.png');}
{% endhighlight %}
<p>
In other words, to give a rule one background image, use
<code>:image</code>; to give it several, use <code>:images</code> (and an
array of values). This applies to all background properties which may take
multiple values:
</p>
<ul>
<li><code>background-image</code>, use <code>:images</code></li>
<li><code>background-origin</code>, use <code>:origins</code></li>
<li><code>background-clip</code>, use <code>:clips</code></li>
<li><code>background-repeat</code>, use <code>:repeats</code></li>
<li><code>background-size</code>, use <code>:sizes</code></li>
<li><code>background-position</code>, use <code>:positions</code></li>
</ul>
<p>
Note that the singular and plural versions are incompatible with one
another; if you use <code>:image</code> in a background declaration you
can’t use <code>:images</code> in the same declaration, and vice
versa.
</p>
</div>