Stylish is a tool that lets you generate CSS 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.
The following tutorial assumes you have Ruby and RubyGems installed. Ruby programming knowledge helps, but should not be essential.
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 Generating CSS with Stylish.
The simplest way to install Stylish is via RubyGems:
sudo gem install stylish
Stylish has no gem dependencies. Ruby 1.8 and Ruby 1.9 are both supported, but using 1.9 is recommended since it makes developing with Stylish that bit more pleasant.
The foundation of the stylesheet generation DSL is the Stylish.generate
method. This
takes a block, and returns a Stylesheet
object.
style = Stylish.generate do
# Your rules here
end
Now to construct some rules. This is done with the rule
method, which must be passed one or more selectors, a hash of
declarations and/or a block.
style = Stylish.generate do
rule "div.section", :margin_bottom => "1em"
end
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 HTML element can be used directly as methods.
style = Stylish.generate do
p :line_height => 1.5
a :text_transform => "uppercase"
end
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.
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;}
Once you’ve created your stylesheet object, you’ll probably
want to serialise it to a file. The Stylesheet
class includes
a print
method for just this eventuality.
style.print('my_style.css')
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 to_s
method.
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;}
Variables are represented by Ruby symbols, and can be used in place of selectors as well as properties.
style = Stylish.generate do
rule :wrapper do
a :color => :bright
end
end
style.to_s :wrapper => "#wrapper", :bright => "f00"
# => #wrapper a {color:#f00;}
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.
Most declaration values are simple strings or numbers. Some, however, have
a more complex internal structure. The most common example is
background
declarations.
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;}
The compressed
flag tells Stylish to use the shorthand form of
the various background-
properties; omitting it will generate
the more specific longhand declarations.
body {
background-color:#fafafa;
background-image:url('bg.png');
background-repeat:no-repeat;
background-position:50% 10px;
}
Variables will work both as a replacement for compound values, substituting the entire hash or array when serialising the stylesheet.
style = Stylish.generate do
body :background => :bodybg
end
style.to_s(:bodybg => {:url => "/images/eyewatering.gif"})
# => body {background-image:url('/images/eyewatering.gif');}
However, they can also be used within the body of the compound value, nested as deeply within the data structure as necessary.
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');}
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.
Stylish attempts to build in forward-compatibility with powerful features of CSS3 such as multiple background images. When using these features in Stylish, two simple rules of thumb should be followed:
To illustrate this, let’s look at two different background declarations.
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');}
In other words, to give a rule one background image, use
:image
; to give it several, use :images
(and an
array of values). This applies to all background properties which may take
multiple values:
background-image
, use :images
background-origin
, use :origins
background-clip
, use :clips
background-repeat
, use :repeats
background-size
, use :sizes
background-position
, use :positions
Note that the singular and plural versions are incompatible with one
another; if you use :image
in a background declaration you
can’t use :images
in the same declaration, and vice
versa.