2013-10-09 12:30:53 +02:00
|
|
|
---
|
2015-04-02 01:51:37 +02:00
|
|
|
title: Sass Basics
|
2018-10-24 00:06:39 +02:00
|
|
|
introduction: >
|
|
|
|
Before you can use Sass, you need to set it up on your project. If you want to
|
|
|
|
just browse here, go ahead, but we recommend you go install Sass first. [Go
|
|
|
|
here](/install) if you want to learn how to get everything setup.
|
2013-10-09 12:30:53 +02:00
|
|
|
---
|
2013-02-11 03:41:27 +01:00
|
|
|
|
2018-10-24 00:06:39 +02:00
|
|
|
- content_for :navigation do
|
2013-10-09 12:30:53 +02:00
|
|
|
%h3 Topics
|
2018-10-24 00:06:39 +02:00
|
|
|
|
2018-12-28 01:31:28 +01:00
|
|
|
%nav.sl-c-list-navigation-wrapper
|
2013-10-09 12:30:53 +02:00
|
|
|
:markdown
|
2018-12-28 01:31:28 +01:00
|
|
|
- [Preprocessing](#topic-1)
|
|
|
|
- [Variables](#topic-2)
|
|
|
|
- [Nesting](#topic-3)
|
|
|
|
- [Partials](#topic-4)
|
|
|
|
- [Import](#topic-5)
|
|
|
|
- [Mixins](#topic-6)
|
|
|
|
- [Inheritance](#topic-7)
|
|
|
|
- [Operators](#topic-8)
|
2018-12-29 02:03:29 +01:00
|
|
|
- [Lists](#topic-9)
|
2018-12-28 01:31:28 +01:00
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
%section#topic-1
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Preprocessing
|
|
|
|
|
|
|
|
CSS on its own can be fun, but stylesheets are getting larger, more
|
|
|
|
complex, and harder to maintain. This is where a preprocessor can help.
|
|
|
|
Sass lets you use features that don't exist in CSS yet like variables,
|
|
|
|
nesting, mixins, inheritance and other nifty goodies that make writing CSS
|
|
|
|
fun again.
|
|
|
|
|
|
|
|
Once you start tinkering with Sass, it will take your preprocessed Sass
|
|
|
|
file and save it as a normal CSS file that you can use in your website.
|
|
|
|
|
|
|
|
The most direct way to make this happen is in your terminal. Once Sass is
|
|
|
|
installed, you can compile your Sass to CSS using the `sass` command.
|
|
|
|
You'll need to tell Sass which file to build from, and where to output CSS
|
|
|
|
to. For example, running `sass input.scss output.css` from your terminal
|
|
|
|
would take a single Sass file, `input.scss`, and compile that file to
|
|
|
|
`output.css`.
|
|
|
|
|
|
|
|
You can also watch individual files or directories with the `--watch`
|
|
|
|
flag. The watch flag tells Sass to watch your source files for changes,
|
|
|
|
and re-compile CSS each time you save your Sass. If you wanted to watch
|
|
|
|
(instead of manually build) your `input.scss` file, you'd just add the
|
|
|
|
watch flag to your command, like so:
|
|
|
|
|
|
|
|
sass --watch input.scss output.css
|
|
|
|
|
|
|
|
You can watch and output to directories by using folder paths as your
|
|
|
|
input and output, and separating them with a colon. In this example:
|
|
|
|
|
|
|
|
= partial 'code-snippets/homepage-sass-watch'
|
|
|
|
|
|
|
|
:markdown
|
|
|
|
Sass would watch all files in the `app/sass` folder for changes, and
|
|
|
|
compile CSS to the `public/stylesheets` folder.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-2
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Variables
|
|
|
|
|
|
|
|
Think of variables as a way to store information that you want to reuse
|
|
|
|
throughout your stylesheet. You can store things like colors, font stacks,
|
|
|
|
or any CSS value you think you'll want to reuse. Sass uses the `$` symbol
|
|
|
|
to make something a variable. Here's an example:
|
|
|
|
|
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
$font-stack: Helvetica, sans-serif;
|
|
|
|
$primary-color: #333;
|
|
|
|
|
|
|
|
body {
|
|
|
|
font: 100% $font-stack;
|
|
|
|
color: $primary-color;
|
|
|
|
}
|
|
|
|
===
|
|
|
|
$font-stack: Helvetica, sans-serif
|
|
|
|
$primary-color: #333
|
|
|
|
|
|
|
|
body
|
|
|
|
font: 100% $font-stack
|
|
|
|
color: $primary-color
|
|
|
|
|
|
|
|
:markdown
|
|
|
|
When the Sass is processed, it takes the variables we define for the
|
|
|
|
`$font-stack` and `$primary-color` and outputs normal CSS with our
|
|
|
|
variable values placed in the CSS. This can be extremely powerful when
|
|
|
|
working with brand colors and keeping them consistent throughout the site.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-3
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Nesting
|
|
|
|
|
|
|
|
When writing HTML you've probably noticed that it has a clear nested and
|
|
|
|
visual hierarchy. CSS, on the other hand, doesn't.
|
|
|
|
|
|
|
|
Sass will let you nest your CSS selectors in a way that follows the same
|
|
|
|
visual hierarchy of your HTML. Be aware that overly nested rules will
|
|
|
|
result in over-qualified CSS that could prove hard to maintain and is
|
|
|
|
generally considered bad practice.
|
|
|
|
|
|
|
|
With that in mind, here's an example of some typical styles for a site's
|
|
|
|
navigation:
|
|
|
|
|
2018-12-28 04:47:31 +01:00
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
nav {
|
|
|
|
ul {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
list-style: none;
|
2018-10-22 21:00:45 +02:00
|
|
|
}
|
2014-07-23 16:48:10 +02:00
|
|
|
|
2018-12-28 04:47:31 +01:00
|
|
|
li { display: inline-block; }
|
2014-07-23 16:48:10 +02:00
|
|
|
|
2018-12-28 04:47:31 +01:00
|
|
|
a {
|
|
|
|
display: block;
|
|
|
|
padding: 6px 12px;
|
|
|
|
text-decoration: none;
|
2018-10-22 21:00:45 +02:00
|
|
|
}
|
2018-12-28 04:47:31 +01:00
|
|
|
}
|
|
|
|
===
|
|
|
|
nav
|
|
|
|
ul
|
|
|
|
margin: 0
|
|
|
|
padding: 0
|
|
|
|
list-style: none
|
|
|
|
|
|
|
|
li
|
|
|
|
display: inline-block
|
|
|
|
|
|
|
|
a
|
|
|
|
display: block
|
|
|
|
padding: 6px 12px
|
|
|
|
text-decoration: none
|
2018-12-28 01:31:28 +01:00
|
|
|
|
|
|
|
:markdown
|
|
|
|
You'll notice that the `ul`, `li`, and `a` selectors are nested inside the
|
|
|
|
`nav` selector. This is a great way to organize your CSS and make it more
|
|
|
|
readable.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-4
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Partials
|
|
|
|
|
|
|
|
You can create partial Sass files that contain little snippets of CSS that
|
|
|
|
you can include in other Sass files. This is a great way to modularize
|
|
|
|
your CSS and help keep things easier to maintain. A partial is simply a
|
|
|
|
Sass file named with a leading underscore. You might name it something
|
|
|
|
like `_partial.scss`. The underscore lets Sass know that the file is only
|
|
|
|
a partial file and that it should not be generated into a CSS file. Sass
|
|
|
|
partials are used with the `@import` directive.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-5
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Import
|
|
|
|
|
|
|
|
CSS has an import option that lets you split your CSS into smaller, more
|
|
|
|
maintainable portions. The only drawback is that each time you use
|
|
|
|
`@import` in CSS it creates another HTTP request. Sass builds on top of
|
|
|
|
the current CSS `@import` but instead of requiring an HTTP request, Sass
|
|
|
|
will take the file that you want to import and combine it with the file
|
|
|
|
you're importing into so you can serve a single CSS file to the web browser.
|
|
|
|
|
2018-12-28 02:28:39 +01:00
|
|
|
Let's say you have a couple of Sass files, `_reset.scss` and `base.scss`.
|
|
|
|
We want to import `_reset.scss` into `base.scss`.
|
2018-12-28 01:31:28 +01:00
|
|
|
|
|
|
|
- example do
|
2018-12-28 23:55:48 +01:00
|
|
|
:plain
|
|
|
|
// _reset.scss
|
|
|
|
html,
|
|
|
|
body,
|
|
|
|
ul,
|
|
|
|
ol {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
---
|
|
|
|
// base.scss
|
|
|
|
@import 'reset';
|
|
|
|
body {
|
|
|
|
font: 100% Helvetica, sans-serif;
|
|
|
|
background-color: #efefef;
|
|
|
|
}
|
|
|
|
===
|
|
|
|
// _reset.sass
|
|
|
|
html,
|
|
|
|
body,
|
|
|
|
ul,
|
|
|
|
ol
|
|
|
|
margin: 0
|
|
|
|
padding: 0
|
|
|
|
---
|
|
|
|
// base.sass
|
|
|
|
@import reset
|
|
|
|
body
|
|
|
|
font: 100% Helvetica, sans-serif
|
|
|
|
background-color: #efefef
|
|
|
|
===
|
|
|
|
html,
|
|
|
|
body,
|
|
|
|
ul,
|
|
|
|
ol {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
body {
|
|
|
|
font: 100% Helvetica, sans-serif;
|
|
|
|
background-color: #efefef;
|
|
|
|
}
|
2018-12-28 01:31:28 +01:00
|
|
|
|
2018-12-29 02:03:29 +01:00
|
|
|
:markdown
|
|
|
|
Notice we're using `@import 'reset';` in the `base.scss` file. When you
|
|
|
|
import a file you don't need to include the file extension `.scss`. Sass
|
|
|
|
is smart and will figure it out for you.
|
2018-12-28 01:31:28 +01:00
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-6
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Mixins
|
|
|
|
|
|
|
|
Some things in CSS are a bit tedious to write, especially with CSS3 and
|
|
|
|
the many vendor prefixes that exist. A mixin lets you make groups of CSS
|
|
|
|
declarations that you want to reuse throughout your site. You can even
|
|
|
|
pass in values to make your mixin more flexible. A good use of a mixin is
|
|
|
|
for vendor prefixes. Here's an example for `transform`.
|
|
|
|
|
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
@mixin transform($property) {
|
|
|
|
-webkit-transform: $property;
|
|
|
|
-ms-transform: $property;
|
|
|
|
transform: $property;
|
|
|
|
}
|
|
|
|
.box { @include transform(rotate(30deg)); }
|
|
|
|
===
|
|
|
|
=transform($property)
|
|
|
|
-webkit-transform: $property
|
|
|
|
-ms-transform: $property
|
|
|
|
transform: $property
|
|
|
|
.box
|
|
|
|
+transform(rotate(30deg))
|
|
|
|
|
|
|
|
:markdown
|
|
|
|
To create a mixin you use the `@mixin` directive and give it a name. We've
|
|
|
|
named our mixin `transform`. We're also using the variable `$property`
|
|
|
|
inside the parentheses so we can pass in a transform of whatever we want.
|
|
|
|
After you create your mixin, you can then use it as a CSS declaration
|
|
|
|
starting with `@include` followed by the name of the mixin.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-7
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Extend/Inheritance
|
|
|
|
|
|
|
|
This is one of the most useful features of Sass. Using `@extend` lets you
|
|
|
|
share a set of CSS properties from one selector to another. It helps keep
|
|
|
|
your Sass very DRY. In our example we're going to create a simple series
|
|
|
|
of messaging for errors, warnings and successes using another feature
|
|
|
|
which goes hand in hand with extend, placeholder classes. A placeholder
|
|
|
|
class is a special type of class that only prints when it is extended, and
|
|
|
|
can help keep your compiled CSS neat and clean.
|
|
|
|
|
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
/* This CSS will print because %message-shared is extended. */
|
|
|
|
%message-shared {
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
padding: 10px;
|
|
|
|
color: #333;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This CSS won't print because %equal-heights is never extended.
|
|
|
|
%equal-heights {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
.message {
|
|
|
|
@extend %message-shared;
|
|
|
|
}
|
|
|
|
|
|
|
|
.success {
|
|
|
|
@extend %message-shared;
|
|
|
|
border-color: green;
|
|
|
|
}
|
|
|
|
|
|
|
|
.error {
|
|
|
|
@extend %message-shared;
|
|
|
|
border-color: red;
|
|
|
|
}
|
|
|
|
|
|
|
|
.warning {
|
|
|
|
@extend %message-shared;
|
|
|
|
border-color: yellow;
|
|
|
|
}
|
|
|
|
===
|
|
|
|
/* This CSS will print because %message-shared is extended. */
|
|
|
|
%message-shared
|
|
|
|
border: 1px solid #ccc
|
|
|
|
padding: 10px
|
|
|
|
color: #333
|
|
|
|
|
|
|
|
|
|
|
|
// This CSS won't print because %equal-heights is never extended.
|
|
|
|
%equal-heights
|
|
|
|
display: flex
|
|
|
|
flex-wrap: wrap
|
|
|
|
|
|
|
|
|
|
|
|
.message
|
|
|
|
@extend %message-shared
|
|
|
|
|
|
|
|
|
|
|
|
.success
|
|
|
|
@extend %message-shared
|
|
|
|
border-color: green
|
|
|
|
|
|
|
|
|
|
|
|
.error
|
|
|
|
@extend %message-shared
|
|
|
|
border-color: red
|
|
|
|
|
|
|
|
|
|
|
|
.warning
|
|
|
|
@extend %message-shared
|
|
|
|
border-color: yellow
|
|
|
|
|
|
|
|
:markdown
|
|
|
|
What the above code does is tells `.message`, `.success`, `.error`, and
|
|
|
|
`.warning` to behave just like `%message-shared`. That means anywhere that
|
|
|
|
`%message-shared` shows up, `.message`, `.success`, `.error`, & `.warning`
|
|
|
|
will too. The magic happens in the generated CSS, where each of these
|
|
|
|
classes will get the same CSS properties as `%message-shared`. This helps
|
|
|
|
you avoid having to write multiple class names on HTML elements.
|
|
|
|
|
|
|
|
You can extend most simple CSS selectors in addition to placeholder
|
|
|
|
classes in Sass, but using placeholders is the easiest way to make sure
|
|
|
|
you aren't extending a class that's nested elsewhere in your styles, which
|
|
|
|
can result in unintended selectors in your CSS.
|
|
|
|
|
|
|
|
Note that the CSS in `%equal-heights` isn't generated, because
|
|
|
|
`%equal-heights` is never extended.
|
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|
|
|
|
|
|
|
|
%section#topic-8
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
## Operators
|
|
|
|
|
|
|
|
Doing math in your CSS is very helpful. Sass has a handful of standard
|
|
|
|
math operators like `+`, `-`, `*`, `/`, and `%`. In our example we're
|
|
|
|
going to do some simple math to calculate widths for an `aside` &
|
|
|
|
`article`.
|
|
|
|
|
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
.container {
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
article[role="main"] {
|
|
|
|
float: left;
|
|
|
|
width: 600px / 960px * 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
aside[role="complementary"] {
|
|
|
|
float: right;
|
|
|
|
width: 300px / 960px * 100%;
|
|
|
|
}
|
|
|
|
===
|
|
|
|
.container
|
|
|
|
width: 100%
|
2013-02-11 03:41:27 +01:00
|
|
|
|
|
|
|
|
2018-12-28 01:31:28 +01:00
|
|
|
article[role="main"]
|
|
|
|
float: left
|
|
|
|
width: 600px / 960px * 100%
|
|
|
|
|
2013-02-11 03:41:27 +01:00
|
|
|
|
2018-12-28 01:31:28 +01:00
|
|
|
aside[role="complementary"]
|
|
|
|
float: right
|
|
|
|
width: 300px / 960px * 100%
|
2013-02-11 03:41:27 +01:00
|
|
|
|
2018-12-28 01:31:28 +01:00
|
|
|
:markdown
|
|
|
|
We've created a very simple fluid grid, based on 960px. Operations in Sass
|
|
|
|
let us do something like take pixel values and convert them to percentages
|
2018-12-28 04:47:31 +01:00
|
|
|
without much hassle.
|
2014-03-14 06:04:34 +01:00
|
|
|
|
2018-12-28 23:55:48 +01:00
|
|
|
## Mixins
|
|
|
|
|
|
|
|
Some things in CSS are a bit tedious to write, especially with CSS3 and
|
|
|
|
the many vendor prefixes that exist. A mixin lets you make groups of CSS
|
|
|
|
declarations that you want to reuse throughout your site. You can even
|
|
|
|
pass in values to make your mixin more flexible. A good use of a mixin is
|
|
|
|
for vendor prefixes. Here's an example for <code>transform</code>.
|
|
|
|
|
|
|
|
- example do
|
|
|
|
:plain
|
|
|
|
@mixin transform($property) {
|
|
|
|
-webkit-transform: $property;
|
|
|
|
-ms-transform: $property;
|
|
|
|
transform: $property;
|
|
|
|
}
|
|
|
|
|
|
|
|
.box { @include transform(rotate(30deg)); }
|
|
|
|
===
|
|
|
|
=transform($property)
|
|
|
|
-webkit-transform: $property
|
|
|
|
-ms-transform: $property
|
|
|
|
transform: $property
|
2014-03-14 06:04:34 +01:00
|
|
|
|
2018-12-28 23:55:48 +01:00
|
|
|
.box
|
|
|
|
+transform(rotate(30deg))
|
2013-02-11 03:41:27 +01:00
|
|
|
|
2018-12-28 23:55:48 +01:00
|
|
|
:markdown
|
|
|
|
To create a mixin you use the <code>@mixin</code> directive and give it a
|
|
|
|
name. We've named our mixin <code>transform</code>. We're also using
|
|
|
|
the variable <code>$property</code> inside the parentheses so we can pass in
|
|
|
|
a transform of whatever we want. After you create your mixin, you can then
|
|
|
|
use it as a CSS declaration starting with <code>@include</code> followed
|
|
|
|
by the name of the mixin.
|
2013-02-11 03:41:27 +01:00
|
|
|
|
2019-03-04 23:41:21 +01:00
|
|
|
---
|