Getting Sassy

A few weeks ago I wrote about haml and mentioned its younger sister language called Sass. I’ve been playing around with Sass for a couple of months now and love it.

Sass is basically a CSS templating language which means that you write your styles in Sass and this then gets compiled on the server side into the CSS that is sent to the browser. It looks similar to CSS (but without the curly braces) and adds all of functionality that you’ve always wished CSS did in the first place. Here is a very basic example:

h1
  color: red
  font-size: 36px

This will compile to:

h1 {
  color: red;
  font-size: 36px;
}

To get Sass working in Sinatra you just need to add the following handler to your code:

get '/main.css' do
  content_type 'text/css', :charset => 'utf-8'
  sass :main
end

Then in your views directory you need to create a file called main.sass. This is where all your Sass code goes. This will then get compiled into a stylesheet called main.css.

I really like the syntax of Sass and prefer not using the curly braces and semi-colons, but if you like your CSS to look like CSS then that’s fine too because there is another flavour of Sass called Scss (Sassy CSS) and this does all the same things as Sass, but looks more like CSS. Have a look at the examples on the Sass homepage for some comparisons.

The main advantages of Sass are Variables, Nesting, Inheritence and Mixins.

Variables

You can set variables to any property you like which helps to make your code much more maintainable - if something changes, you only have to change it in one place:

$heading-color: red
$heading-size: 13px

h1
  color: $heading-color
  font-size: $heading-size

Nesting

No need to write out the same selectors over and over again. So if you want to style a paragraph that is inside a div with an id of ‘content’, you could just write this:

#content
  background: pink
    p
      color: purple

This will compile as:

#content {
  background: pink;
}

#content p {
  color: purple;
}

What’s nice is you can also nest property values too:

p
  font:
    weight: bold
    family: helvetica
    size: 12px

Inheritance

A selector can inherit the styles from other classes. This allows you to take a much more object-orientated approach to CSS and build up some base styles.

.heading
  color: red

.big-heading
  @extend .heading
  font-size: 48px

This will compile as:

.heading {
  color: red;
}

.big-heading {
  color: red;
  font-size: 48px;
}

Mixins

This is where the fun really starts. You can define some basic styles and then mix them into other selectors. This helps you to avoid repetition and build up a library of commonly used styles.

Here’s how you define a mixin:

=uglyheader
  color: red
  font-size: 36px

And here’s how you mix it in:

h1
  +uglyheader

Simple!

Here are a few mixins that I’ve come up with. They mainly make CSS3 properties a bit easier to handle by avoiding all the browser vendor specific code.

Rounded Corners

Mix this in to give anything rounded corners.

=rounded($topleft: 10px,$bottomleft:$topleft,$bottomright: $bottomleft,             $topright:$topleft)
  -moz-border-radius: $topleft $topright $bottomright     $bottomleft
  -webkit-border-radius: $topleft $topright $bottomright $bottomleft
  border-radius: $topleft $topright $bottomright $bottomleft

Rotations

Rotate elements any number of degrees

=rotate($angle: 30)
  -webkit-transform: rotate($angle + deg)
  -moz-transform: rotate($angle + deg)
  transform: rotate($angle + deg)

Enlargements

Make elements bigger or smaller using CSS3 transformations.

=scale($scalefactor: 1.2)
  -webkit-transform: scale($scalefactor)
  -moz-transform: scale($scalefactor)
  transform: scale($scalefactor)

Drop Shadows

Get that professional drop-shadow look with a single line of code:

=boxshadow($colour: rgba(0,0, 0, 0.8),$weight: 6px,$blur: 14px)
  -webkit-box-shadow: $weight $weight $blur $colour
  -moz-box-shadow: $weight $weight $blur $colour
  box-shadow: $weight $weight $blur $colour

Gradients

Pure CSS gradients with a simple mixin. Choose either one colour to get darker or two colours to blend. Needs testing in Internet Explorer.

=gradient($start: #CCCCCC,$finish: darken($start,25%),$stop: 1)
  -webkit-background-clip: padding-box
  background: $start
  background-image: -moz-linear-gradient(top, $start 0%, $finish percentage($stop))
  background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, $start),color-stop($stop, $finish))
  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=#{$start + 'FF'}, EndColorStr=#{$finish + 'FF'})
  -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr=#{$start + 'FF'}, EndColorStr=#{$finish + 'FF'})"
  background-image: linear-gradient(top, $start 0%, $finish percentage($stop))

Image Replacement

Replace an element with a background image.

=imagereplace($name,$width,$height,$ext: png,$units: px)
  background: url(/images/ + $name + "." + $ext) transparent 0 0 no-repeat
  display: block
  padding: 0
  text-indent: -12345px
  height: $height + $units
  width: $width + $units

Clearfix

Really useful whey you’re trying to do complicated floated layouts. This will make sure that any elements that are floated inside will be contained inside and cleared.

=clearfix
  _height: 1%
  *min-height: 1px
  zoom: 1
  &:after
    content: "."
    display: block
    height: 0
    clear: both
    visibility: hidden
blog comments powered by Disqus