I set out to learn about front-end architecture with grid systems because I haven’t done hands-on work with a grid system before, but quickly it became clear that I needed to learn some Sass fundamentals. Here’s a walkthrough of the features I learned about and my tips for folks at the same stage of learning.
First of all, for shame that my life has been Sass-less. I know many Sass developers and even attended the inaugural SassConf last year, so I have no excuse for not having used it on a personal project before. As a former full-time CSS writer, Sass always looked weird and confusing to me. I could grasp the use of variables and math, but pretty much everything else just seemed really complicated.
I started with the Team Treehouse Sass Basics course. It moves at a fairly slow pace, but is taught by the creator of Sass Hampton Catlin who is fairly silly in his presentation style, so it’s fun to watch. The super-simplified explanations helped me understand and internalize how Sass differs from CSS. Instantly, I could see how Sass makes CSS more Ruby-like, something I’m quite comfortable with on day thirty-something of my Ruby course.
Sass makes CSS more Ruby-like
After I became comfortable with the basic syntax of Sass, I gave up the Treehouse videos in favor of a great beginner slide deck that allowed me to work at my own pace: https://speakerdeck.com/anotheruiguy/sass-101-a-newbs-guide
Working with Sass
If you’re not in a Rails app that already has Sass, assuming you have Ruby installed, you can gem install sass
. Then all you need to start working with Sass is a something.scss
file. Run sass --watch .
to have Sass watch your current directory and automatically compile something.css
every time you save something.scss
Alternately, if you just want to see how the language works, you can try out the examples in Sassmeister
An important thing to know about working with Sass is that you don’t have to use any of it’s features if you don’t want. You can write plain old CSS in your Sass file and it will render fine, so you can really use the level of Sass you’re comfortable with and grow to the more advanced features gradually.
Nesting and Variables
One of the major banes of CSS is having to repeat yourself over and over again, and Hampton tells us in the Treehouse videos that the first and primary goal of Sass is not having to repeat yourself as much. Two of the simplest tools for this are nesting and variables.
When Sass compiles, it automatically writes the repetitive CSS selectors based on the nesting present in your Sass file. The &
signifies a direct parent relationship. So, for example:
Sass:
.content .blog-entry {
margin: 20px 0;
p {
color: gray;
line-height: 1.2em;
}
a {
color: blue;
&:hover {
text-decoration: underline;
}
}
}
Compiled CSS:
.content .blog-entry {
margin: 20px 0;
}
.content .blog-entry p {
color: gray;
line-height: 1.2em;
}
.content .blog-entry a {
color: blue;
}
.content .blog-entry a:hover {
text-decoration: underline;
}
Not massively different, but you can see how on a real project with a large amount of style, this can save you considerable repetition. It also makes updating class names simple.
Variables can be defined with the $
operator to further DRY out your stylesheets.
Sass:
$full-screen: 900px;
$small-screen: 320px;
.content {
width: $full-screen;
@media only screen and (max-width: $small-screen) {
width: 97%;
}
}
Compiled CSS:
.content {
width: 900px;
}
@media only screen and (max-width: 320px) {
.content {
width: 97%;
}
}
Extends
Extends allow you to add a selector to a previously defined block of code.
Sass:
.blog .entry {
h1 {
color: black;
font: {
size: 2em;
weight: bold;
variant: small-caps;
}
}
h2 {
font-size: 1.5em;
@extend h1
}
}
CSS:
.blog .entry h1, .blog .entry h2 {
color: black;
font-size: 2em;
font-weight: bold;
font-variant: small-caps;
}
.blog .entry h2 {
font-size: 1.5em;
}
You can also use %
to denote “silent extends” for reusable code blocks.
Sass:
%marquee-text {
font: {
size: 3em;
family: Merriweather;
}
}
.content-marquee {
color: gray;
@extend %marquee-text;
}
.media-marquee {
color: purple;
@extend %marquee-text;
}
Compiled CSS:
.content-marquee, .media-marquee {
font-size: 3em;
font-family: Merriweather;
}
.content-marquee {
color: gray;
}
.media-marquee {
color: purple;
}
At this point, I’m not sure why silent extends exist, given mixins, but I’m just learning so I’ll give it some time to sink in.
Mixins
Mixins allow you to use the same block of style in various places throughout your code. The @mixin
keyword is used to define a mixin block. If you pretend @mixin
is def
it all feels comfortably like a Ruby method!
@mixin border($radius, $style) {
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius;
border: $style;
}
.blog .entry {
@include border(5px, 3px solid white);
}
Mixins also support string interpolation(!)
Sass:
@mixin standard-border($side) {
border-#{$side}: solid 1px gray;
}
.header {
@include standard-border("top");
}
CSS:
.header {
border-top: solid 1px gray;
}
The thing that blew my mind the most (so far) is that Sass has an @each
keyword that allows you to iterate in your stylesheet. Sass is seriously a dream come true for a CSS-er turned Ruby-ist.
Sass has an
@each
keyword that allows you to iterate in your stylesheet
Sass
@each $profile in github, twitter, linkedin {
.#{$profile}-icon {
width: 50px;
height: 50px;
background-image: url('/images/#{$profile}.png')
}
}
CSS:
.github-icon {
width: 50px;
height: 50px;
background-image: url("/images/github.png");
}
.twitter-icon {
width: 50px;
height: 50px;
background-image: url("/images/twitter.png");
}
.linkedin-icon {
width: 50px;
height: 50px;
background-image: url("/images/linkedin.png");
}
Now that I know some basics of Sass, I’m ready to tackle the grid systems I set out to explore. Stay tuned!
Sass references/resources:
Sass 101 speaker deck – Dale Sande
Sass Basics – Team Treehouse, Hampton Catlin