mirror of
https://github.com/danog/sass-site.git
synced 2024-12-11 17:09:52 +01:00
392 lines
12 KiB
Plaintext
392 lines
12 KiB
Plaintext
---
|
|
title: Sass Basics
|
|
---
|
|
|
|
%p.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.
|
|
= link_to "Go here", "/install"
|
|
if you want to learn how to get everything setup.
|
|
|
|
- content_for :complementary do
|
|
%h3 Topics
|
|
%ul.anchors
|
|
%li= link_to "Preprocessing", "#topic-1"
|
|
%li= link_to "Variables", "#topic-2"
|
|
%li= link_to "Nesting", "#topic-3"
|
|
%li= link_to "Partials", "#topic-4"
|
|
%li= link_to "Import", "#topic-5"
|
|
%li= link_to "Mixins", "#topic-6"
|
|
%li= link_to "Inheritance", "#topic-7"
|
|
%li= link_to "Operators", "#topic-8"
|
|
|
|
%ul.slides
|
|
%li#topic-1
|
|
: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.
|
|
|
|
%hr/
|
|
|
|
%li#topic-2
|
|
: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
|
|
<code>$</code> 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
|
|
<code>$font-stack</code> and <code>$primary-color</code> 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.
|
|
|
|
%hr/
|
|
|
|
%li#topic-3
|
|
: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:
|
|
|
|
~ partial "code-snippets/example-nesting.html.erb"
|
|
|
|
:markdown
|
|
You'll notice that the <code>ul</code>, <code>li</code>, and
|
|
<code>a</code> selectors are nested inside the <code>nav</code> selector.
|
|
This is a great way to organize your CSS and make it more readable.
|
|
|
|
%hr/
|
|
|
|
%li#topic-4
|
|
: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 <code>_partial.scss</code>. 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 <code>@import</code> directive.
|
|
|
|
***
|
|
|
|
%li#topic-5
|
|
: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
|
|
<code>@import</code> in CSS it creates another HTTP request. Sass builds
|
|
on top of the current CSS <code>@import</code> 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.
|
|
|
|
Let's say you have a couple of Sass files, <code>\_reset.scss</code> and
|
|
<code>base.scss</code>. We want to import <code>\_reset.scss</code> into
|
|
<code>base.scss</code>.
|
|
|
|
- example do
|
|
: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;
|
|
}
|
|
|
|
:markdown
|
|
|
|
Notice we're using <code>@import 'reset';</code> in the
|
|
<code>base.scss</code> file. When you import a file you don't need to
|
|
include the file extension <code>.scss</code>. Sass is smart and will
|
|
figure it out for you.
|
|
|
|
%hr/
|
|
|
|
%li#topic-6
|
|
: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 <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
|
|
|
|
.box
|
|
+transform(rotate(30deg))
|
|
|
|
: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.
|
|
|
|
%hr/
|
|
|
|
%li#topic-7
|
|
:markdown
|
|
## Extend/Inheritance
|
|
|
|
This is one of the most useful features of Sass. Using
|
|
<code>@extend</code> 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 <code>.message</code>,
|
|
<code>.success</code>, <code>.error</code>, & <code>.warning</code>
|
|
to behave just like <code>%message-shared</code>. That means anywhere
|
|
that <code>%message-shared</code> shows up, <code>.message</code>,
|
|
<code>.success</code>, <code>.error</code>, & <code>.warning</code>
|
|
will too. The magic happens in the generated CSS, where each of these
|
|
classes will get the same CSS properties as <code>%message-shared</code>.
|
|
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 <code>%equal-heights</code> isn't generated, because
|
|
<code>%equal-heights</code> is never extended.
|
|
|
|
%hr/
|
|
|
|
%li#topic-8
|
|
: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%
|
|
|
|
|
|
article[role="main"]
|
|
float: left
|
|
width: 600px / 960px * 100%
|
|
|
|
|
|
aside[role="complementary"]
|
|
float: right
|
|
width: 300px / 960px * 100%
|
|
|
|
: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
|
|
without much hassle.
|