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