SASS is a way to create dynamic styles that render into CSS. SASS is a better way to write and manage styles because of nesting and selector inheritance. Without further ado, let's learn more about SASS!

Nesting in SASS

Nesting selectors in SASS provides a more organized approach to writing styles. In SASS, nesting selectors allows for a style sheet that resembles your DOM structure instead of normal CSS. The best way to learn about nesting is by example:

<div class="foo">
    <div class="bar">&nbsp</div>
</div>
.foo {
    background: white;
    .bar {
        background: black;
    }
}

/* CSS OUTPUT */
/* .foo { background: white; } */
/* .foo .bar { background: black; } */

If we place our source code and SASS script back-to-back we will see:

<div class="foo">
    <!-- .bar is a child of .foo -->
    <div class="bar">
        &nbsp;
    </div>
</div>
            
.foo {
    background: white;
    .bar { // .bar is a child of .foo
        background: black;
    }
}
            

We can easily see how SASS strives to duplicate the DOM structure and give people an idea of how the elements are nested within the DOM.

The only magic to utilizing this method is to simply change how your code is written. Instead of indicating a parent-child relationship via .foo .bar (as we might do in conventional CSS) we can physically write .bar inside of .foo as the example above suggests.

Here are more complex examples:

&lt;div class=&quot;block&quot;&gt;
    &lt;p&gt;Foo bar&lt;/p&gt;
    &lt;div class=&quot;inner&quot;&gt;
        &lt;img src=&quot;foo.jpg&quot; alt=&quot;Foo Bar&quot;&gt;
        &lt;p&gt;Foo Bar Image&lt;/p&gt;
    &lt;/div&gt;
&lt;/div&gt;
div.block {
    width: 150px;
    height: 150px;
    background: rgba(0,0,0,0.25);
    p {
        font-size: 10px;
        color: white;
    }
    .inner {
        margin: 0 auto;
        text-align: center;
        background: rgba(255,255,255,0.1);
        border: 1px solid rgba(0,0,0,0.25);
        p {
            background: rgba(0,0,0,0.5);
            color: #ff9300; /* overrides div.block p */
            text-shadow: 0 0 1px 2px black;
            padding: 3px;
        }
    }
}

Dissecting the code, we have an idea of our DOM structure:

 div.block \rightarrow p \\ div.block  \rightarrow .inner \\ div.block \rightarrow .inner \rightarrow p

We could explain the relationship in English as well:

  • div.block has a child called p
  • div.block has a child called .inner
    • .inner has a child called p

Stressing a parental relationship:

  • p has a parent called div.block
  • .inner has a parent called div.block
    • p has a parent called .inner
    • p has a grandparent called div.block

Given the relationship above, we can predict the CSS output and where our defined styles will be applied to. For instance, p will have the styles we defined if p is a child of div.block.

Here is our CSS result:

div.block {
  width: 150px;
  height: 150px;
  background: rgba(0, 0, 0, 0.25);
}

div.block p {
  font-size: 10px;
  color: white;
}

div.block .inner {
  margin: 0 auto;
  text-align: center;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(0, 0, 0, 0.25);
}
div.block .inner p {
  background: rgba(0, 0, 0, 0.5);
  color: #ff9300; /* overrides div.block p */
  text-shadow: 0 0 1px 2px black;
  padding: 3px;
}

Referencing Parent Selectors

SASS offers the ability to reference parent selectors which enables us quickly add styles without unnecessary repetition.

When referencing parent selectors we must use nested syntax and the & (ampersand).

Note: the ampersand & is a reserved character in SASS, if you need a literal & then use \0026

.foo {
    color: white;
    &amp;:hover {
        color: black;
    }
}

This is a very simple example of referencing a parent selector and using the pseudo-class :hover. Our output is:

.foo { color: white; }
.foo:hover { color: black; }

Initially, it might be difficult to grasp how convenient this can be. Let's see a better example!
Below is a snippet from Dave Gamache's Skeleton CSS Framework

.button, 
button, 
input[type=&quot;submit&quot;], 
input[type=&quot;reset&quot;], 
input[type=&quot;button&quot;] {
	background: #eeeeee linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -moz-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -ms-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -o-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.2)), color-stop(100%, rgba(0, 0, 0, 0.2)));
	background: #eeeeee -webkit-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee;
	border: 1px solid #aaaaaa;
	border-left: 1px solid #cccccc;
	border-radius: 3px;
	border-top: 1px solid #cccccc;
	color: #444444;
	cursor: pointer;
	display: inline-block;
	font-family: &quot;HelveticaNeue&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
	font-size: 11px;
	font-weight: bold;
	line-height: normal;
	margin-bottom: 20px;
	moz-border-radius: 3px;
	padding: 8px 10px;
	text-decoration: none;
	text-shadow: 0 1px rgba(255, 255, 255, 0.75);
	webkit-border-radius: 3px;
}
.button:hover, 
button:hover, 
input[type=&quot;submit&quot;]:hover, 
input[type=&quot;reset&quot;]:hover, 
input[type=&quot;button&quot;]:hover {
	background: #dddddd linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
	background: #dddddd -moz-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
	background: #dddddd -ms-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
	background: #dddddd -o-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
	background: #dddddd -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.3)), color-stop(100%, rgba(0, 0, 0, 0.3)));
	background: #dddddd -webkit-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
	background: #dddddd;
	border: 1px solid #888888;
	border-left: 1px solid #aaaaaa;
	border-top: 1px solid #aaaaaa;
	color: #222222;
}
.button:active, 
button:active, 
input[type=&quot;submit&quot;]:active, 
input[type=&quot;reset&quot;]:active, 
input[type=&quot;button&quot;]:active {
	background: #cccccc linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
	background: #cccccc -moz-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
	background: #cccccc -ms-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
	background: #cccccc -o-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
	background: #cccccc -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.35)), color-stop(100%, rgba(10, 10, 10, 0.4)));
	background: #cccccc -webkit-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
	background: #cccccc;
	border: 1px solid #666666;
}
.button.full-width, 
button.full-width, 
input[type=&quot;submit&quot;].full-width, 
input[type=&quot;reset&quot;].full-width, 
input[type=&quot;button&quot;].full-width {
	padding-left: 0 !important;
	padding-right: 0 !important;
	text-align: center;
	width: 100%;
}

As wonderful of a framework as this is, we can translate this into a SASS script and see the power of referencing parent selectors:

.button, 
button, 
input[type=&quot;submit&quot;], 
input[type=&quot;reset&quot;], 
input[type=&quot;button&quot;] {
    background: #eeeeee linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -moz-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -ms-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -o-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.2)), color-stop(100%, rgba(0, 0, 0, 0.2)));
	background: #eeeeee -webkit-linear-gradient(top, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%);
	background: #eeeeee;
	border: 1px solid #aaaaaa;
	border-left: 1px solid #cccccc;
	border-radius: 3px;
	border-top: 1px solid #cccccc;
	color: #444444;
	cursor: pointer;
	display: inline-block;
	font-family: &quot;HelveticaNeue&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
	font-size: 11px;
	font-weight: bold;
	line-height: normal;
	margin-bottom: 20px;
	moz-border-radius: 3px;
	padding: 8px 10px;
	text-decoration: none;
	text-shadow: 0 1px rgba(255, 255, 255, 0.75);
	webkit-border-radius: 3px;
    &amp;:hover {
        background: #dddddd linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
        background: #dddddd -moz-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
    	background: #dddddd -ms-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
    	background: #dddddd -o-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
    	background: #dddddd -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.3)), color-stop(100%, rgba(0, 0, 0, 0.3)));
    	background: #dddddd -webkit-linear-gradient(top, rgba(255, 255, 255, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%);
    	background: #dddddd;
    	border: 1px solid #888888;
    	border-left: 1px solid #aaaaaa;
    	border-top: 1px solid #aaaaaa;
    	color: #222222;
    }
    &amp;:active {
        background: #cccccc linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
        background: #cccccc -moz-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
    	background: #cccccc -ms-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
    	background: #cccccc -o-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
    	background: #cccccc -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0.35)), color-stop(100%, rgba(10, 10, 10, 0.4)));
    	background: #cccccc -webkit-linear-gradient(top, rgba(255, 255, 255, 0.35) 0%, rgba(10, 10, 10, 0.4) 100%);
    	background: #cccccc;
        border: 1px solid #666666;
    }
    &amp;.full-width {
        padding-left: 0 !important;
        padding-right: 0 !important;
    	text-align: center;
    	width: 100%;
    }
}

Our end result will be identical so why is this so awesome anyway? Consider we needed to add an element to this list. Using pure CSS we will need to add the extra element three or four times before it is applied. Using SASS, however, we can add it once and with referencing parent selectors we can let the compiler figure the everything out.

Another feature of SASS, similar to vanilla CSS, is we have the ability to group selectors, even when referencing a parent or utilizing the alternative syntax.

nav {
    ul {
        margin: 0;
        padding: 0;
        li {
            list-style: none;
            float: left;
            margin-right: 10px;
            &amp;:hover, // grouping for li:hover and li.active
            &amp;.active { background: rgba(255,255,255,0.4); }
            a {
                color: #ff9300;
                text-decoration: underline;
                &amp;:hover, // a:hover
                &amp;:active, // a:active
                &amp;.active { // a.active
                    color: #804a00;
                    text-decoration: none;
                }
            }
        }
    }
}

And our CSS rendering:

nav ul {
	margin: 0;
	padding: 0;
}
nav ul li {
	list-style: none;
	float: left;
	margin-right: 10px;
}
nav ul li:hover, 
nav ul li.active { background: rgba(255, 255, 255, 0.4); }
nav ul li a {
	color: #ff9300;
	text-decoration: underline;
}
nav ul li a:hover, 
nav ul li a:active,
nav ul li a.active {
	color: #804a00;
	text-decoration: none;
}

Nested Properties

Nested properties is an interesting feature of SASS. This enables us to use a single basic property and literally split it up into its individual properties. Let's say, for instance, we look at the margin property. We can define this particular property several different ways:

html {
	/* Condensed form */
	margin: [top] [right] [bottom] [left];
	margin: [top] [right/left] [bottom];
	margin: [top/bottom] [right/left];
	margin: [top/right/bottom/left];
	
	/* Individual */
	margin-top: [top];
	margin-right: [right];
	margin-bottom: [bottom];
	margin-left: [left];
}

Looking at the margin we clearly see many different ways to get the same result. The condensed form is a single property while the individual forms are four separate properties. In SASS, we can isolate these four properties by identifying the margin parent property and then defining each child property separately. Here is what we mean:

body {
	margin: {
		top: 4px;
		right: 5px;
		bottom: 6px;
		left: 7px;
	};
}

Bizarre—no?
Nested properties is yet another way to define properties with multiple sub-properties in that nested-style syntax that keeps coming back. Not surprisingly, our result will be:

body {
	margin-top: 4px;
	margin-right: 5px;
	margin-bottom: 6px;
	margin-left: 7px;
}

Here are more examples:

body {
	font: {
		family: &quot;Trebuchet MS&quot;, Tahoma, Arial, sans-serif;
		size: 2em;
		weight: bold;
		style: italic;
	}
}

Will render to:

body {
	font-family: &quot;Trebuchet MS&quot;, Tahoma, Arial, sans-serif;
	font-size: 2em;
	font-weight: bold;
	font-style: italic;
}
Be Sociable, Share!