Intro to Theming With Sass

WordCamp Miami 2014

Created by Josh Eaton / @jjeaton

Who Am I?

Indianapolis, IN
Developer / Partner, Reaktiv Studios
Genesis Design Palette Pro
Almost a dad

Agenda

  • Sass Intro
  • Why Sass?
  • Sass Compilation Apps
  • Sass Features
  • Frameworks

What is Sass?

A CSS Pre-processor

A What in the What?

PHP, HTML, CSS, JavaScript

I have to learn ANOTHER language?

Sass == CSS + Extensions

PHP, HTML, Sass, JavaScript

Two Syntaxes


h2 {
  color: red;

  a {
    text-decoration: none;
  }
}
                    

h2
  color: red

  a
    text-decoration: none
                    

Why use a CSS Pre-Processor?

  • Maintainability
  • Efficiency, fewer errors
  • DRY(er) code
  • WordPress Core uses Sass for admin color schemes as of 3.8

Other pre-processors are great (Less/Stylus) but we're going to focus on Sass.

When Should you NOT use a CSS Pre-Processor?

  • Not sole developer
  • Not responsible for maintenance
  • Client wants to maintain

Your first Sass file

  1. Take *any* CSS file
  2. Rename it to .scss
  3. ???
  4. Profit, err, Compile it!

Sass Compilation

Command Line


$ gem install sass
$ mv style.css style.scss
$ sass style.scss style.css
                    

Install Sass ruby gem and run compiler.

Oh Noes, not the command line!

There's an app for that.

Sass Features

  • Partials (@import finally!)
  • Nesting
  • Comments
  • Variables
  • Mixins
  • Inheritance (@extend)
  • Frameworks

Partials

Filenames beginning with an underscore are assumed to be partials.

style.scss

You should never use @import in CSS, but always in Sass.


@import "bits";
@import "defaults";
@import "typography";
@import "layout";
@import "nav";
@import "comments";
@import "forms";
                    

Sass assumes the '_' and file extension for files in the same directory.

Nesting


.content h2 a {
    color: green;
}
.content h2 a:hover,
.content h2 a:focus {
    color: hotpink;
}
                    

Nesting


.content {
    h2 {
        a {
            color: green;
        }
        a:hover,
        a:focus {
            color: hotpink;
        }
    }
}
                    

Nesting

&: Reference the parent selector.


.module {
    a {
        color: blue;
        &:hover, &:focus {
            color: red;
            body.contact & { color: green; }
        }
    }
}
                    

.module a {
    color: blue;
}
.module a:hover, .module a:focus {
    color: red;
}
body.contact .module a:hover, body.contact .module a:focus {
    color: green;
}
                    

Nesting

Watch your specificity!


body.team-page {
    background-color: blue;
    .team {
        .person {
            background-color: red;
        }
    }
}
                    

Comments


/*
  This comment will appear in the compiled CSS
 */

// You can say whatever you want in here
// because it won't end up in the CSS
                    

Comments

Keep theme header info intact


/*!
Theme Name: WCMIA 2014 SASS
Theme URI: http://reaktivstudios.com/
Author: Reaktiv Studios
Author URI: http://reaktivstudios.com/
Description: Custom theme for WCMIA.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wcmia-2014
*/

@import ...
                    

Variables

Set and reuse values anywhere.


$bodyBG: #343434;
$headerText: #268bd2;

body {
    background-color: $bodyBG;
}
h1 {
    color: $headerText;
}
                    

Mixins

Define reusable sets of styles.


@mixin font-stack-icons {
    font-family: "icomoon";
    font-weight: normal;
    font-style: normal;
}

.icon-arrow::before {
    @include font-stack-icons;
    content: "\e601"
}
                    

Mixins

Pass parameters to change behavior.


@mixin bp($point) {
    @if $point == middle {
        @media (max-width: 105em) { @content; }
    }
    @if $point == small {
        @media (max-width: 75em) { @content; }
    }
    @if $point == very-small {
        @media (max-width: 50em) { @content; }
    }
}

                    

I use this on every project.

Mixins


.content {
    p {
        font-size: 1.6em;
        @include bp(small) {
            font-size: 1.4em;
        }
        @include bp(very-small) {
            font-size: 1em;
        }
    }
}
                    

.content p { font-size: 1.6em; }

@media (max-width: 75em) {
  .content p { font-size: 1.4em; }
}
@media (max-width: 50em) {
  .content p { font-size: 1em; }
}
                    

Inheritance

Allow elements to inherit properties from other classes/selectors.


.button {
    background-color: #eaeaea;
    border: 2px solid #ddd;
    border-radius: 5px;
}

.subscribe-button {
    @extend .button;
    text-transform: uppercase;
}
.comment-button {
    @extend .button;
    border-color: black;
}
                    

Inheritance


.button, .subscribe-button, .comment-button {
    background-color: #eaeaea;
    border: 2px solid #ddd;
    border-radius: 5px;
}
.subscribe-button {
    text-transform: uppercase;
}
.comment-button {
    border-color: black;
}
                    

Inheritance

Roll your own simple, semantic grid system.


...

%griditem {
    float: left;
    padding-right: 2em;
}
%grid-1-3 { width: 33.3333%; }
%grid-2-3 { width: 67.6767%; }

.content {
    @extend %griditem;
    @extend %grid-2-3;
}
.content {
    @extend %griditem;
    @extend %grid-1-3;
}
                    

Mixins vs. Inheritance

Mixins repeat code in compiled CSS.

@extend builds a selector chain and writes the CSS once.

Use a mixin if you need to pass a parameter, otherwise @extend may be a better fit for repeated styles.

Frameworks

Creating Sprites with Compass

Never create a sprite by hand again.


@import "social-icons/*.png";
                    

.social a {
    @include social-icons-sprite(twitter);
    width: social-icons-sprite-width(twitter);
    height: social-icons-sprite-height(twitter);
}
                    

THE END

Questions?