Getting Sassywith CSS – Julie Cameron – Getting Sassy with CSS



Getting Sassywith CSS – Julie Cameron – Getting Sassy with CSS

8 6


SassShop

An introduction to Sass workshop originally created for Girl Develop It Detroit.

On Github jewlofthelotus / SassShop

Get Setup!

Wifi Network: atomic-detroit-public

Password: atomicpublic

Recommended Dev Tools:

Sublime Text

Terminal or Command Prompt

Google Chrome

LivePage

Get Ready!

Install Sass (via Command Line)

Setup the Project

Command Line Tutorial

Welcome!

Girl Develop It is here to provide affordable and accessible programs to learn software through mentorship and hands-on instruction.

Some "rules"

  • We are here for you!
  • Every question is important
  • Help each other
  • Have fun!

Julie Cameron

JulieCameron.com | @JewlOfTheLotus | jewlofthelotus@gmail.com

  • Remote Frontender for Articulate
  • Sassy CSS Fan
  • Modular Architecture Proponent
  • Responsive Web Design Advocate
  • Open Source JS & WP Developer
  • Working Remote
  • SlickQuiz
  • Full Time Sass for 1 year

Meet the team!

What is your name?

What type of development experience do you have?

What is your favorite kind of cookie?

Well you all rule because I love all cookies, my nickname as a child was "the cookie monster."

Getting Sassy with CSS

#SassShopDetroit

First sass class in Detroit

You're all very cutting edge right now

Getting Sassy with CSS

What is Sass The Sass Workflow Sass Basics Advanced Sass Media Queries Modular Architecture Libraries & Tools Wrap-Up

The Project...

Client: Kittens "R" Us

Description: An adoption listing website for local kitties in need of homes.

Documentation: Setup Instructions

Slides: gdidetroit.com/sass

Nothing too special, just something to play around with - but feel free to go all out!

I HIGHLY recommend that you DL these slides and refer back to them as we're going through exercises

You're welcome to follow the examples exactly, or customize things as we go.

And Feel free to try things out as I'm presenting, I don't want you to feel like you need to wait for the exercise to experiment.

Section I

What is Sass?

WHY The Trouble with CSS

  • Websites are becoming increasingly complex.
  • CSS is getting harder to maintain.
  • Writing styles is often tedious and repetitive.
  • CSS can only do so much for us...
  • bigger and more modular
  • our needs for organization are increasing
  • repetition - think vendor prefixes, think linear gradients

Enter Sass

Syntactically Awesome StyleSheets

Like CSS but BETTERIt addresses the previously mentioned shortcomings

PRO TIP It's Sass, not SASS

Sass Origins

Sass Trifecta of Awesome

Tools like Sass, Less and Stylus have live-tested features and impelemnations that will likely inspire features in future CSS specifications.

So let's get a taste of what Sass can do for us by digging into one of CSSs pain-points: repetition.

Repetition

                .header {
                  background-color: #531946;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .header a {
                  color: #fff;
                }
                .header a:hover {
                  color: #095169;
                }

                .footer {
                  background-color: #30162B;
                  color: #fff;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .footer a {
                  color: #095169;
                }
                .footer a:hover {
                  color: #fff;
                }

                .feature a {
                  background-color: #30162B;
                  color: #fff;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .feature a:hover {
                  color: #531946;
                }

                .content {
                  background-color: #fff;
                  color: #222;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
              

DRY

Don't Repeat Yourself

HEX Colors

Border Radius + Padding

Selectors

development principle aimed at reducing repetition

HINT: the syntax highlighting might give you a few ideas

Colors >> Padding >> Selectors

So let's see what Sass can do for us in these scenarios, starting with colors...

Repetition Colors

CSS

                .header {
                  background-color: #531946;
                }
                .header a {
                  color: #fff;
                }
                .header a:hover {
                  color: #095169;
                }

                .footer {
                  background-color: #30162B;
                  color: #fff;
                }
                .footer a {
                  color: #095169;
                }
                .footer a:hover {
                  color: #fff;
                }

                .feature a {
                  background-color: #30162B;
                  color: #fff;
                }

                .feature a:hover {
                  color: #531946;
                }

                .content {
                  background-color: #fff;
                  color: #222;
                }
              

Sass Variables

                $white: #ffffff;
                $black: #222222; // NOT! ;)
                $eggplant: #531946;
                $eggplantDark: #30162B;
                $teal: #095169;

                .header {
                  background-color: $eggplant;
                }
                .header a {
                  color: $white;
                }
                .header a:hover {
                  color: $teal;
                }

                .footer {
                  background-color: $eggplantDark;
                  color: $white;
                }
                .footer a {
                  color: $teal;
                }
                .footer a:hover {
                  color: $white;
                }

                .feature a {
                  background-color: $eggplantDark;
                  color: $white;
                }

                .feature a:hover {
                  color: $eggplant;
                }

                .content {
                  background-color: $white;
                  color: $black;
                }
              

No one wants to remember #531946

Wouldn't it be nice if we had a way to store and reference our colors?

Repetition Border Radius + Padding

CSS

                .header {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .footer {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .feature a {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .content {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }
              

Sass Mixins

                @mixin rounded-box {
                  border-radius: 5px;
                  padding: 5px 20px;
                }

                .header {
                  @include rounded-box;
                  // ...
                }

                .footer {
                  @include rounded-box;
                  // ...
                }

                .feature a {
                  @include rounded-box;
                  // ...
                }

                .content {
                  @include rounded-box;
                  // ...
                }
              

It looks like we've got a default box style

What if we could set those defaults in one place and reference it elsewhere?

Repetition Selectors

CSS

                .header {
                  /* ... */
                }
                .header a {
                  /* ... */
                }
                .header a:hover {
                  /* ... */
                }

                .footer {
                  /* ... */
                }
                .footer a {
                  /* ... */
                }
                .footer a:hover {
                  /* ... */
                }

                .feature a {
                  /* ... */
                }
                .feature a:hover {
                  /* ... */
                }

                .content {
                  /* ... */
                }
              

Sass Nesting

                .header {
                  // ...

                  a {
                    // ...

                    &:hover {
                      // ...
                    }
                  }
                }

                .footer {
                  // ...

                  a {
                    // ...

                    &:hover {
                      // ...
                    }
                  }
                }

                .feature a {
                  // ...

                  &:hover {
                    // ...
                  }
                }

                .content {
                  // ...
                }
              

What if I want to change .header to .banner? I have to edit it everywhere

What if we had a way of only referencing these repeated selectors once?

What if we could nest our selectors just like we can in our HTML?

RECAP Repetition

CSS

                .header {
                  background-color: #531946;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .header a {
                  color: #fff;
                }
                .header a:hover {
                  color: #095169;
                }

                .footer {
                  background-color: #30162B;
                  color: #fff;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .footer a {
                  color: #095169;
                }
                .footer a:hover {
                  color: #fff;
                }

                .feature a {
                  background-color: #30162B;
                  color: #fff;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
                .feature a:hover {
                  color: #531946;
                }

                .content {
                  background-color: #fff;
                  color: #222;
                  border-radius: 5px;
                  padding: 5px 20px;
                }
              

Sass

                $white:        #ffffff;
                $grey:         #222222;
                $eggplant:     #531946;
                $eggplantDark: #30162B;
                $teal:         #095169;

                // Mixins
                @mixin rounded-box {
                  border-radius: 5px;
                  padding: 5px 20px;
                }

                // Site Stylez
                .header {
                  @include rounded-box;
                  background-color: $eggplant;

                  a {
                    color: $white;
                    &:hover { color: $teal; }
                  }
                }

                .footer {
                  @include rounded-box;
                  background-color: $eggplantDark;
                  color: $white;

                  a {
                    color: $teal;
                    &:hover { color: $white; }
                  }
                }

                .feature a {
                  @include rounded-box;
                  background-color: $eggplantDark;
                  color: $white;

                  &:hover { color: $eggplant; }
                }

                .content {
                  @include rounded-box;
                  background-color: $white;
                  color: $grey;
                }
              

Colors (vars), Border Radius + Padding (mixin), Selectors (nesting)

RECAP Why Sass?

  • Reduced complexity.
  • Increased maintainability.
  • Minimized repetition.
  • Supercharged CSS!

Alright, so now that we've gotten a taste of it in action, let's get an official definition

What is Sass?

Sass is an extension of CSS that adds power and elegance to the basic language. It allows you to use variables, nested rules, mixins, inline imports, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized, and get small stylesheets up and running quickly...

~ Sass Documentation

Any valid CSS file is a valid Sass file

What is Sass?

CSS Extension

SassScript Language

CSS Preprocessor

SassScript Interpreter

Sass CSS

Sass is an extension of CSS, but we can't load Sass in the browser like we can CSS

May seem like 2 separate tools, but they're really just one, and more often then not, you'll hear them referred to as a singluar tool.

Two Syntaxes

.scss (Sassy CSS)Default syntax; Valid CSS == Valid SCSS

                $black: #000;
                $white: #fff;

                .this {
                  color: $black;
                  background: $white;
                }

                .that {
                  color: $white;
                  background: $black;
                }

                .this, .that {
                  display: block;

                  &:hover {
                    border: 1px solid;
                  }
                }
              

.sass (Indented)Original syntax, still supported; Haml-esque

                $black: #000
                $white: #fff

                .this
                  color: $black
                  background: $white

                .that
                  color: $white
                  background: $black

                .this, .that
                  display: block
                  &:hover
                    border: 1px solid
              

Because valid CSS is also valid SCSS, getting started with Sass is as easy as changing the file extension.

Start slow, add in features as you learn / get more comfortable.

Section II

The Sass Workflow

Sass Installation

Ruby

OS X? Lucky you, it's preinstalled!

Windows? Try RubyInstaller.

Sass

$ gem install sass

Running Sass

Sass CSS

$ sass source.scss output.css

$ sass source_dir output_dir

So let's get a more visual representation...

Running Sass

  • project_awesome
    • index.html
    • sass
      • screen.scss
    • css
      • screen.css

$ sass sass/screen.scss css/screen.css

At this point you might be thinking

Well gosh, do I need to run this command EVERY single time I make a change?

And the answer is of course not! That's what watching is for!

Sass Is Watching You...

$ sass --watch source.scss:output.css
This is the best thing EVER.
Gotchya: Colon vs. Space
  • works with single files and entire directories
  • ...let's look at some more commands

More Sassy Options

$ sass source.scss output.css
Compile source.scss to output.css. Gotchya: will fail if output directory doesn't exist.
$ sass --update source.scss:output.css
Compile source.scss to output.css. Will create new directories if they don't exist.
$ sass --watch source.scss:output.css
Watch source.scss for changes. Same syntax as --update.
$ sass --style expanded source.scss:output.css
Adjusts output format. Options: nested, expanded, compact, compressed

I'm going to get into some code to explain the style option more...

Demo Sass Workflow

Exercise - Section 2

  • sass sass/screen.scss css/screen.css
  • sass --update sass/screen.scss:css/screen.css
  • sass --watch sass/screen.scss:css/screen.css
  • sass --style expanded sass/screen.scss:css/screen.css
  • sass --style compact sass/screen.scss:css/screen.css
  • sass --style compressed sass/screen.scss:css/screen.css

Section II Let's develop it!

  • Duplicate this project structure.
  • In the head of index.html, include a link to your CSS output
  • Open index.html in the broswer, optionally enable LivePage**
  • Open screen.scss, add a few basic styles and save the file.
  • Run (on one line): sass --watch --style expanded sass/screen.scss:css/screen.css
  • Checkout your page in the browser to see your sassy new stylez.
  • PRO Add MOAR stylez!!
  • project_awesome
    • index.html
    • sass
      • screen.scss
    • css
** You will need to enable "Allow access to file URLs" for LivePage in chrome://extensions

Section III

Sass Basics

Alright, so now that we know generally what Sass is and how it works

let's get into the basics

Sass Basics

Nesting Variables Imports & Organization

Imports are critical for a modular and organized architecture

3.1 Nesting

  • HTML has a clear hierarchy - elements are nested
  • We can do the same thing with Sass

HTML

                <nav class="navigation">
                  <ul>
                    <li><a href="#">Home</a></li>
                    <li><a href="#about">About</a></li>
                    <li><a href="#contact">Contact</a></li>
                  </ul>
                </nav>
              

Sass

                .navigation {
                  float: right;

                  li {
                    display: inline-block;
                    list-style-type: none;
                    margin-left: 1.5em;
                  }

                  a {
                    display: block;
                    text-decoration: none;
                  }
                }
              

THIS IS MY FAVORITE THING.

It's the one thing that I instantly miss when writing vanila CSS.

I do it by habit and intuition now.

Let's look at the output of that...

Nesting Output

Sass

                .navigation {
                  float: right;

                  li {
                    display: inline-block;
                    list-style-type: none;
                    margin-left: 1.5em;
                  }

                  a {
                    display: block;
                    text-decoration: none;
                  }
                }
              

CSS Output

                .navigation {
                  float: right;
                }

                .navigation li {
                  display: inline-block;
                  list-style-type: none;
                  margin-left: 1.5em;
                }

                .navigation a {
                  display: block;
                  text-decoration: none;
                }
              
  • Sass gives us organization
  • Sass reduces repetition

So, there's kid of a gotchya with nesting though...

Nesting Gotchya

  • Mirroring HTML nesting is SUPER easy
  • Overly verbose and overly specific
  • Rule of thumb: no more than 3 levels deep

Sass

                body {
                  .header {
                    .navigation {
                      ul {
                        li {
                          a {
                            // ...
                          }
                        }
                      }
                    }
                  }
                }
              

CSS Output

                body .header .navigation ul li a {
                  // ...
                }
              

Work WITH the cascade, not against it

Nesting too deeply results in specificity nightmares and fragile, unmaintainable code

Nesting Let's develop it!

  • Add the header on the right to your index.html.
  • In screen.scss, nest styles that:
    • Display header h1 and header nav as inline-block
    • Float header nav to the right
    • Display nav li as inline-block, with no bullets, and a 1em left margin
    • Display nav a as block with no text-decoration, 10px padding, and your choice of background and color colors
                <header class="header">
                  <h1>My Site Title</h1>
                  <nav class="navigation">
                    <ul>
                      <li><a href="#">Home</a></li>
                      <li><a href="#about">About</a></li>
                      <li><a href="#contact">Contact</a></li>
                    </ul>
                  </nav>
                </header>
              

RememberDon't nest too deeply!

PRO Add MOAR stylez

Nesting Parent Selectors

Sass allows us to reference the current parent selector(s) via the ampersand character:

Sass

                a {
                  color: #beedee;

                  &:hover {
                    color: #cbbebb;
                  }

                  &.btn {
                    background: #deede6;
                  }

                  .btn {
                    display: block;
                  }
                }
              

CSS Output

                a {
                  color: #beedee;
                }

                a:hover {
                  color: #cbbebb;
                }

                a.btn {
                  background: #deede6;
                }

                a .btn {
                  display: block;
                }
              

The ampersand will reference the entire chain of parent selectors

Nesting Parent Selectors

The & selector can follow other selectors. This will override the parent element's (&) styles when it exists within the preceding selector.

Sass

                a {
                  .footer & {
                    text-decoration: none;

                    span {
                      opacity: .5;
                    }
                  }

                  span {
                    .navigation & {
                      display: block;
                    }
                  }
                }
              

CSS Output

                .footer a {
                  text-decoration: none;
                }

                .footer a span {
                  opacity: .5;
                }

                .navigation a span {
                  display: block;
                }
              

So this can be really really helpful, especially if you're familiar with the concept of modifiers as they relate to the concepts of OOCSS and BEM.

What you're essentially doing is modifying the parent selector

We'll jump quickly into OOCSS and BEM later, but you'll see hints of it throughout the shop

& Selector Let's develop it!

  • Add the .footer on the right to index.html.
  • Move nav styles out of the header so they'll apply to nav anywhere**
  • Use parent selector nesting to:
    • Float nav to the right only if it's within the .header
    • Change the background color of nav a on :hover
    • Set the .navigation li to have 1em right margin, by default; and 1em left margin if it exists within .header
                <footer class="footer">
                  <nav class="navigation">
                    <ul>
                      <li><a href="#">Home</a></li>
                      <li><a href="#about">About</a></li>
                      <li><a href="#contact">Contact</a></li>
                    </ul>
                  </nav>
                </footer>
              

** You may need to readjust your nesting

Alright, so before we move on from nesting there is one more thing I'd like to cover

Nesting Properties

You can also nest namespaced properties

Sass

                a {
                  border: {
                    color: #deedee;
                    style: solid;
                    width: 2px;
                  }
                }
              

CSS Output

                a {
                  border-color: #deedee;
                  border-style: solid;
                  border-width: 2px;
                }
              

Not only can you nest selectors

ALRIGHT, so that was nesting, let's move on to the next basic...

Sass Basics

Variables

We already saw a sampling of variables when we talked about repetition, so we know that they help to

  • Reduce repetition
  • Improve maintainability
  • Make Find & Replace! unecessary or at least easier

So let's see what ELSE we can use variables for

3.2 Variables

Some Uses

  • colors
  • font sizes
  • font families
  • font paths
  • padding
  • margins
  • breakpoints

Some More Uses

  • border-radius
  • content
  • gradients
  • shadows
  • SELECTORS!
  • LOGIC!
  • ALL THE THINGS!!!1!

you can put just about anything in a variable and so for that reason, it's a very very valuable tool for dealing with the repetition and tediousness of CSS

so how do we use em...

Variables Assignment & Reference

Variables are defined like normal CSS rules(property: value;), only prefixed with a $

Variables are then referenced by their $-prefixed names.

Sass

                $grey: rgba(0,0,0,.5);
                $teal: #095169;
                $default-padding: 1em;

                a {
                  color: $teal;
                  padding: $default-padding;
                  &:hover {
                    color: $grey;
                    background: $teal;
                  }
                }

                p {
                  padding-bottom: $default-padding
                }
              

CSS Output

                a {
                  color: #095169;
                  padding: 1em;
                }
                a:hover {
                  color: rgba(0,0,0,.5);
                  background: #095169;
                }
                p {
                  padding-bottom: 1em;
                }
              

as you can see, we've set a few different types of data - there a total of 6 data types that Sass accepts

Variable Data Types

Types

  • Numbers
  • Strings
  • Colors
  • Lists
  • Booleans
  • Null

Uses

                $base-padding: 10px;
                $line-height: 1.5;

                $base-font: Verdana;
                $content: "Loading...";

                $feature-color: purple;
                $feature-background: rgba(0, 255, 0, 0.5);

                $base-margin: 20px 0 30px 10px;
                $base-font: "Trebuchet MS", "Verdana", "Arial";

                $bordered: true;
                $shadowed: false;

                $secondary: null;
              

NUMBERS can be set with or without units

STRINGS can be set with or without quotes

we'll get into things like lists, booleans, and null later, but they can be super helpful

now, there are two ways to define variables, the first is Simple Assignment

Variable Simple Assignment

You can redeclare variables to override previous values

Sass

                $border-width: 2px;
                $border-width: 4px;

                a {
                  border: $border-width solid $teal;
                }
              

CSS Output

                a {
                  border: 4px solid #095169;
                }
              

simple assignment: create a variable, assign it a value

you can also override these values

This is especially helpful when theming or working with third party tools

Variable Guarded Assignment

The !default flagMeans: set if it does not already have a value

Sass

                $border-width: 2px;
                $border-width: 4px !default;

                a {
                  border: $border-width solid $teal;
                }
              

CSS Output

                a {
                  border: 2px solid #095169;
                }
              

a lot of 3rd party libraries use guarded assignment so that you can override their values before including the code

so this leads us nicely into scope

Variable Scope

Variables are only available within the level of nested selectors where they're defined.

If they're defined outside of any nested selectors, they're available everywhere.

~ Sass Documentation

Sass

                $border-width: 4px; // Global

                a {
                  $color: orange;   // Local
                  border: $border-width solid green;
                }

                p {
                  border: $border-width solid red;
                  color: $color; // ERROR!!
                  // Undefined variable "$color"
                }
              

This is sort of a global / local setup

Variable Globals

Setting new values to "global" variables within a selector changes future instances of that variable

Sass

                $border-width: 4px;

                a {
                  $border-width: 2px;
                  border: $border-width solid green;
                }

                p {
                  border: $border-width solid red; //=> 2px
                }
              

We can change global variables anywhere

We can only create or change local variables within that nesting level

So this brings us to the last aspect of variables - interpolation

Variable Interpolation

Variables can be injected into selectors, property names, and strings with #{$variable}

Sass

                $side: left;

                .box-#{$side} {
                  border-#{$side}: 1px solid #ccc;

                  &:before {
                    content: "It's on the #{$side} side";
                  }
                }
              

CSS Output

                .box-left {
                  border-left: 1px solid #ccc;
                }
                .box-left:before {
                  content: "It's on the left side";
                }
              

We'll see how this can become pretty handy later on

PROTIP Variable Naming

OK Variables

                $white: #ffffff;
                $black: #222222;
                $eggplant: #531946;
                $eggplantDark: #30162B;
                $teal: #095169;

                .header {
                  background-color: $eggplant;
                }
                .header a {
                  color: $white;
                }
                .header a:hover {
                  color: $teal;
                }

                .footer {
                  background-color: $eggplant-dark;
                  color: $white;
                }
                .footer a {
                  color: $teal;
                }
                .footer a:hover {
                  color: $white;
                }

                .feature a {
                  background-color: $eggplant-dark;
                  color: $white;
                }

                .feature a:hover {
                  color: $eggplant;
                }

                .content {
                  background-color: $white;
                  color: $black;
                }
              

Better Variables

                // Descriptive Colors
                $white:        #ffffff;
                $grey:         #222222;
                $eggplant:     #531946;
                $eggplantDark: #30162B;
                $teal:         #095169;

                // Functional Colors
                $header--background:          $eggplant;
                $header__logo--color:         $white;
                $header__logo--color--hover:  $teal;

                $footer--background:          $eggplant--dark;
                $footer--color:               $white;
                $footer__nav--color:          $teal;
                $footer__nav--color--hover:   $white;

                $content--background:         $white;
                $content--color:              $grey;

                $feature__link--background:   $eggplant--dark;
                $feature__link--color:        $white;
                $feature__link--color--hover: $eggplant;

                .header {
                  background-color: $header--background;
                }
                .header a {
                  color: $header__logo--color;
                }
                .header a:hover {
                  color: $header__logo--color--hover;
                }

                .footer {
                  background-color: $footer--background;
                  color: $footer--color;
                }
                .footer a {
                  color: $footer__nav--color;
                }
                .footer a:hover {
                  color: $footer__nav--color--hover;
                }

                .feature a {
                  background-color: $feature__link--background;
                  color: $feature__link--color;
                }

                .feature a:hover {
                  color: $eggplant;
                }

                .content {
                  background-color: $content--background;
                  color: $content--color;
                }
              

You want to be crafty with naming, but also don't spend too much time worrying about them, they're easy enough to update later once patterns become more apparent

Variables Let's develop it!

  • Colors:
    • Find a color pallete
    • Set color and background for header, content, footer* and nav items
    • Abstract colors to variables, name based on usage
  • Fonts:
    • Set variables for different base and heading font-family stacks**
    • Set html to use the base variable, and h1...h6 to your heading variable

* Hint: Set footer background on html so it fills the entire bottom of the page

** Try a fancy font or two from google!

PRO Add MOAR stylez

So we're not going to focus too much on globals or overrides or interpolation at this stage, let's just get comfortable with setting and using variables

Sass Basics

Imports & Organization

3.3 Imports & Organization

  • CSS @import has always meant an extra file download
  • Sass modifies @import to instead include the resource during compilation, rather than on the client side

Organization OMGZZ!

              @import "vars";

              @import "compass";
              @import "fontawesome";

              @import "utilities";

              @import "grid";
              @import "base";

              @import "modules/all";
              @import "pages/all";
            

Imports

@import takes a path to a Sass resource, the file extension is optional

These @imports look for resources within the main Sass file's parent directory

                @import "vars";

                @import "compass";
                @import "fontawesome";

                @import "utilities";

                @import "grid";
                @import "base";

                @import "modules/all";
                @import "pages/all";
              

Now when I say MAIN SASS FILE we're starting to get into file organization here...

Imports File Structure

screen.scss

                @import "vars";
                @import "lib/compass";
                @import "lib/fontawesome";
                @import "utilities";
                @import "grid";
                @import "base";
              

$ sass sass/screen.scss css/screen.css

  • project_awesome
    • sass
      • lib
        • compass.scss
        • fontawesome.scss
      • base.scss
      • grid.scss
      • screen.scss
      • utilities.scss
      • vars.scss
    • css
      • screen.css
    • index.html
  • screen.scss would be considered our "main" sass file, it's where we import and organize our project
  • the @import paths reference files in the same directory or nested below
  • so if we were to run this sass command, we'd end up with screen.css
  • Now there's sort of a gotchya here...

Imports Compiling Directories

$ sass sass/ css/

  • sass
    • lib
      • compass.scss
      • fontawesome.scss
    • base.scss
    • grid.scss
    • screen.scss
    • utilities.scss
    • vars.scss

  • css
    • lib
      • compass.css
      • fontawesome.css
    • base.css
    • grid.css
    • screen.css
    • utilities.css
    • vars.css

if we compile the whole directory, we get output for every file

running sass on directories will compile all Sass files regardless of whether or not they've been included elsewhere

how do we fix that? what if we wanted to compile a screen and a print stylesheet and didn't want to run multiple sass commands...

Imports Partials

$ sass sass/ css/

  • sass
    • lib
      • _compass.scss
      • _fontawesome.scss
    • _base.scss
    • _grid.scss
    • print.scss
    • screen.scss
    • _utilities.scss
    • _vars.scss

  • css
    • print.css
    • screen.css
  • An _underscore creates a partial
  • Partials will not compile to .css on their own, they must be @imported
  • Partials allow us to break up our code into more modular, maintainable chunks!

partial help us break up our code in the

Imports Organization

Common Practices

  • _vars.scss is a separate sheet for all your variables
  • _vars.scss is added first so that it's variables can override later !defaulted ones
  • Variables > Libraries > Base > Modules > PagesOOCSS, BEM, SMACSS, Atomic Design
  • Modular Architecture

screen.scss

                // Variables
                @import "vars";

                // Libraries
                @import "lib/compass";
                @import "lib/fontawesome";

                // Base Styles, Utility Classes, etc.
                @import "base/all";

                // Individual Components
                @import "modules/all";

                // Page Styles
                @import "pages/all";
              

Ultimately, how you organize your code is up to you

Imports Let's develop it!

  • Update your project's file structure to look something like the one on the right
  • Move ALL styles from screen.scss to more modular / organized locations
  • Update screen.scss to @import your new partials

PRO Add MOAR stylez

  • project_awesome
    • sass
      • base
        • _vars.scss
        • _base.scss
      • modules
        • _header.scss
        • _footer.scss
        • _navigation.scss
      • screen.scss

Break Time!

Enjoy some snacks courtesy of Atomic Object!

Part 1 Review

Sass Intro

Workflow

Nesting

Variables

Imports & Organization

Questions?

Section IV

Advanced Sass

Advanced Sass

Mixins (@include) Inheritence (@extend) Math & Color Directives (Overview)

Mixins

Variables let you reuse single values.

Mixins let you reuse blocks of styles.

So let's look at some code...

Mixins Use

CSS

                .header {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .footer {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .feature a {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .content {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }
              

Sass Mixins

                @mixin rounded-box {
                  border-radius: 5px;
                  padding: 5px 20px;
                }

                .header {
                  @include rounded-box;
                  // ...
                }

                .footer {
                  @include rounded-box;
                  // ...
                }

                .feature a {
                  @include rounded-box;
                  // ...
                }

                .content {
                  @include rounded-box;
                  // ...
                }
              

Earlier we saw this CSS example where we're repeating the same border-radius and padding over and over

They're sort of default settings, if you will

We can make this more maintainable, by pulling these out into one location

let's dig into this code a bit more...

Mixins Setup

                @mixin rounded-box {
                  border-radius: 5px;
                  padding: 5px 20px;
                }

                .header {
                  @include rounded-box;
                  color: $header-color;
                  // ...
                }

                .footer {
                  @include rounded-box;
                  // ...
                }

                .feature a {
                  @include rounded-box;
                  // ...
                }

                .content {
                  @include rounded-box;
                  // ...
                }
              
  • We define a mixin with the @mixin directive
  • We reference a mixin with the @include directive
  • Mixins must be defined before they're referenced
  • Mixins accept optional arguments
  • Mixins can be used with any other style rules
  • You can nest within mixins just like you can elsewhere

Now, let's look at what's actually happening here before we move on

defined before referenced -- partials / imports

So let's see what this actually outputs

Mixins Output

Sass

                @mixin rounded-box {
                  border-radius: 5px;
                  padding: 5px 20px;
                }

                .header {
                  @include rounded-box;
                  color: $header-color;
                  // ...
                }

                .footer {
                  @include rounded-box;
                  // ...
                }

                .feature a {
                  @include rounded-box;
                  // ...
                }

                .content {
                  @include rounded-box;
                  // ...
                }
              

CSS Output

                .header {
                  border-radius: 5px;
                  padding: 5px 20px;
                  color: $header-color;
                  /* ... */
                }

                .footer {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .feature a {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .content {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }
              

We're still just repeating properties here....

Mixins Efficiency

Mixin Output

                .header {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .footer {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .feature a {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }

                .content {
                  border-radius: 5px;
                  padding: 5px 20px;
                  /* ... */
                }
              

CSS Grouping

                .header,
                .footer,
                .feature a,
                .content {
                  border-radius: 5px;
                  padding: 5px 20px;
                }
              

It'd actually be more efficient just to group the classes together.

So what's a good use case for mixins then...

Mixins CSS3

Vendor Prefixes?!

                @mixin rounded-corners {
                  -webkit-border-radius: 10px;
                     -moz-border-radius: 10px;
                          border-radius: 10px;
                }

                .header {
                  @include rounded-corners;
                  // ...
                }

                .footer {
                  @include rounded-corners;
                  // ...
                }
              

But... we're still really just copying the same properties and values all over the place.

How about anything with vendor prefixes?

Those things get repetitive, it'd be nice to have a one liner right?

But..

alright, so when the hell are mixins useful then?...

Mixins Arguments

Sass

                @mixin rounded-corners($radius) {
                  -webkit-border-radius: $radius;
                     -moz-border-radius: $radius;
                          border-radius: $radius;
                }

                .header {
                  @include rounded-corners(5px);
                  // ...
                }

                .footer {
                  @include rounded-corners(10px);
                  // ...
                }
              

CSS Output

                .header {
                  -webkit-border-radius: 5px;
                     -moz-border-radius: 5px;
                          border-radius: 5px;
                  // ...
                }

                .footer {
                  -webkit-border-radius: 10px;
                     -moz-border-radius: 10px;
                          border-radius: 10px;
                  // ...
                }
              

Mixins are great for repeated blocks of styleswhere the values differ from case to case.

I mentioned before that mixins can accept arguments

Output..

Mixins are great for repeated blocks of properties where the values differ from case to case...

Mixins Argument Defaults

You can also set an argument's default value,making it optional to pass one in.

Sass

                @mixin rounded-corners($radius: 5px) {
                  -webkit-border-radius: $radius;
                     -moz-border-radius: $radius;
                          border-radius: $radius;
                }

                .header {
                  @include rounded-corners;
                  // ...
                }

                .footer {
                  @include rounded-corners(10px);
                  // ...
                }
              

CSS Output

                .header {
                  -webkit-border-radius: 5px;
                     -moz-border-radius: 5px;
                          border-radius: 5px;
                  // ...
                }

                .footer {
                  -webkit-border-radius: 10px;
                     -moz-border-radius: 10px;
                          border-radius: 10px;
                  // ...
                }
              

Arguments are required, unless you set a default

Now let's go a level deeper here...

Mixins