CSS is crafted to be simple, but over time your styles become large and your files become bloated with selectors growing out of control. Scaling simplicity is difficult.
When you scale CSS:
- Slight variations of colors, fonts, numbers & other properties arise
- Effective curbing of repetition can decline.
- Stylesheet size may become unmanageable
Enter Sass, the Syntactically Awesome Stylesheets.
What is Sass?
Here is what Sass is:
- Looks like CSS, but adds features to combat shortcomings.
- Preprocessor, like CoffeeScript & Haml
- Sassy CSS (.scss) is the default file extension.
- CSS is valid SCSS
style.scss
$main: #444;
.btn {
color: $main;
display: block;
}
.btn-a {
color: lighten($main, 30%);
&:hover {
color: lighten($main, 40%);
}
}
style.css
.btn {
color: #444444;
display: block;
}
.btn-a {
color: #919191;
}
.btn-a:hover {
color: #aaaaaa;
}
Comments
Sass adds //
for single line comments - not output after compile
style.scss
// These comments will
// not be output to the
// compiled CSS file
/* This comment will */
style.css
/* This comment will */
Avoid CSS @import
The CSS @import rule should be avoided to as it prevents parallel downloading. @import with .scss or .sass happens during compile rather than client-side. Which file extension to use is optional.
application.scss
// Imports styles found in 'buttons.scss'
// when the compiler processes application.scss
@import "buttons";
Partials
Adding an underscore creates a partial. Partials can be imported, but will not compile to .css
application.scss
// Will import _buttons.sass, buttons.sass,
// _buttons.scss, or buttons.scss
@import "buttons";
Nesting Selectors
Consider the Sass file below:
.content {
border: 1px solid #ccc;
padding: 20px;
}
.content h2 {
font-size: 3em;
margin: 20px 0;
}
.content p {
font-size: 1.5em;
margin: 15px 0;
}
When compiled the CSS output will look like:
.content {
border: 1px solid #ccc;
padding: 20px;
}
.content h2 {
font-size: 3em;
margin: 20px 0;
}
.content p {
font-size: 1.5em;
margin: 15px 0;
}
Pretty much the same. The whole point of using Sass is to structure your styles in a way easier for you to interpret what you are intending to do. Now look at the following Sass file:
.content {
border: 1px solid #ccc;
padding: 20px;
}
h2 {
font-size: 3em;
margin: 20px 0;
}
p {
font-size: 1.5em;
margin: 15px 0;
}
This will generate the same CSS file as above, but we have nested selectors in our Sass file.
Nesting Properties
Certain properties with matching namespaces are nestable:
.btn {
text: {
decoration: underline;
transform: lowercase;
}
}
.btn {
text-decoration: underline;
text-transform: lowercase;
}
While nesting, the & symbol references the parent selector:
application.scss
.content {
border: 1px solid #ccc;
padding: 20px;
.callout {
border-color: red;
}
&.callout {
border-color: green;
}
}
application.css
.content {
border: 1px solid #ccc;
padding: 20px;
}
.content .callout {
border-color: red;
}
.content.callout {
border-color: green;
}
Above, & references .content
application.scss
a {
color: #999;
&:hover {
color: #777;
}
&:active {
color: #888;
}
}
application.css
.sidebar {
float: right;
width: 300px;
}
.sidebar h2 {
color: #777;
}
.users .sidebar h2 {
color: #444;
}
Nesting is easy but dangerous, so do not nest unnecessarily.
Here's an example where over-using nesting can become messy.
application.scss
.content {
background: #ccc;
.cell {
h2 {
a {
&:hover {
color: red;
}
}
}
}
}
application.css
.content {
background: #ccc;
}
.content .cell h2 a:hover {
color: red;
}
Here the outcome has a dangerous level of specificity.