Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Clean CSS with Sass and Bourbon

Fce8312709a551df9b0a9311ae0f843b?s=47 Phil LaPier
April 24, 2012

Clean CSS with Sass and Bourbon

Fce8312709a551df9b0a9311ae0f843b?s=128

Phil LaPier

April 24, 2012
Tweet

Transcript

  1. CLEAN CSS WITH SASS AND BOURBON @PHIL LAPIER DESIGNER THOUGHTBOT

  2. CSS

  3. PAST ➞ PRESENT⇢ FUTURE

  4. PAST ➞ PRESENT⇢ FUTURE CSS 1 CSS 2 CSS 2.1

  5. CSS 2.1 aka “dinosaur”

  6. BONUS ROUND but first...

  7. What month & year did CSS 2.1 reach official recommendation

    stage?
  8. June 7, 2011

  9. PAST ➞ PRESENT⇢ FUTURE CSS 2.1 CSS 3 CSS 1

    CSS 2 CSS 2.1
  10. CSS 3 ZOMG, the future!

  11. NEW SELECTORS

  12. BORDER-RADIUS

  13. BOX-SHADOWS

  14. GRADIENTS

  15. ANIMATIONS

  16. VENDOR PREFIXES

  17. -WEBKIT- -MOZ- -MS- -O-

  18. SECTION#BORDER-IMAGE SECTION.DEMO{-WEBKIT-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;-MOZ-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;-O-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;WIDTH:81PX;HEIGHT:27PX;BORDER-

    WIDTH:27PX}SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE{BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#8FDCE5,#3DC3D1);HEIGHT:50PX;WIDTH:100PX} SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE.SINGLE{-WEBKIT-BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65);-MOZ-BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65);BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65)}SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE.DOUBLE{-WEBKIT-BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE;-MOZ-BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE;BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE} SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1{BORDER:1PX SOLID #076FE4;-WEBKIT-BORDER-RADIUS:3PX;-MOZ-BORDER-RADIUS:3PX;BORDER-RADIUS:3PX;- WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;COLOR:#FFF;DISPLAY:INLINE- BLOCK;FONT-SIZE:11PX;FONT-WEIGHT:700;BACKGROUND-COLOR:#4294F0;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#4294F0,#0776F3);TEXT- DECORATION:NONE;TEXT-SHADOW:0 1PX 0 #0065D6;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;PADDING:7PX 18PX}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1:HOVER{-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;CURSOR:POINTER;BACKGROUND-COLOR:#2F87EA;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#2F87EA,#086FE3)}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1:ACTIVE{BORDER:1PX SOLID #076FE4;-WEBKIT-BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE;-MOZ- BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE;BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2{BORDER:1PX SOLID #3371B2;-WEBKIT-BORDER-RADIUS:16PX;-MOZ-BORDER-RADIUS: 16PX;BORDER-RADIUS:16PX;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;COLOR:#FFF;DISPLAY:INLINE-BLOCK;FONT-SIZE:11PX;FONT-WEIGHT:400;LINE-HEIGHT: 1;BACKGROUND-COLOR:#4294F0;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#4294F0,#0156FE);TEXT-ALIGN:CENTER;TEXT-DECORATION:NONE;TEXT-SHADOW:0 -1PX 1PX #2762BF;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;BORDER-COLOR:#3371B2 #2457A3 #164297;PADDING:5PX 16PX}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2:HOVER{BORDER:1PX SOLID #2062A7;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #519CF0;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #519CF0;BOX- SHADOW:INSET 0 1PX 0 0 #519CF0;CURSOR:POINTER;BACKGROUND-COLOR:#2D88EE;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#2D88EE,#1554CE);TEXT-SHADOW: 0 -1PX 1PX #134FAF;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;BORDER-COLOR:#2062A7 #0E479A #01318E}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2:ACTIVE{BACKGROUND:#226EDD;BORDER:1PX SOLID #0D3C8C;BORDER-BOTTOM:1PX SOLID #062D8D;-WEBKIT-BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;-MOZ-BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;TEXT-SHADOW: 0 -1PX 1PX #1A52AA}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-3{BORDER:1PX SOLID #8A0000;BORDER-BOTTOM:1PX SOLID #810000;-WEBKIT-BORDER- RADIUS:5PX;-MOZ-BORDER-RADIUS:5PX;BORDER-RADIUS:5PX;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #FF1D0C;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #FF1D0C;BOX-
  19. SECTION#BORDER-IMAGE SECTION.DEMO{-WEBKIT-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;-MOZ-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;-O-BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;BORDER-IMAGE:URL(../IMAGES/BORDER.PNG) 27 REPEAT;WIDTH:81PX;HEIGHT:27PX;BORDER-

    WIDTH:27PX}SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE{BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#8FDCE5,#3DC3D1);HEIGHT:50PX;WIDTH:100PX} SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE.SINGLE{-WEBKIT-BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65);-MOZ-BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65);BOX-SHADOW:0 0 5PX 3PX RGBA(0,0,0,0.65)}SECTION#BOX-SHADOW SECTION.DEMO DIV.EXAMPLE.DOUBLE{-WEBKIT-BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE;-MOZ-BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE;BOX-SHADOW:1PX 1PX 5PX 1PX GREEN, -1PX -1PX 5PX 1PX BLUE} SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1{BORDER:1PX SOLID #076FE4;-WEBKIT-BORDER-RADIUS:3PX;-MOZ-BORDER-RADIUS:3PX;BORDER-RADIUS:3PX;- WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;BOX-SHADOW:INSET 0 1PX 0 0 #8EBCF1;COLOR:#FFF;DISPLAY:INLINE- BLOCK;FONT-SIZE:11PX;FONT-WEIGHT:700;BACKGROUND-COLOR:#4294F0;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#4294F0,#0776F3);TEXT- DECORATION:NONE;TEXT-SHADOW:0 1PX 0 #0065D6;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;PADDING:7PX 18PX}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1:HOVER{-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;BOX-SHADOW:INSET 0 1PX 0 0 #60A2EC;CURSOR:POINTER;BACKGROUND-COLOR:#2F87EA;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#2F87EA,#086FE3)}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-1:ACTIVE{BORDER:1PX SOLID #076FE4;-WEBKIT-BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE;-MOZ- BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE;BOX-SHADOW:INSET 0 0 8PX 4PX #0868D3, INSET 0 0 8PX 4PX #0868D3, 0 1PX 1PX 0 #EEE}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2{BORDER:1PX SOLID #3371B2;-WEBKIT-BORDER-RADIUS:16PX;-MOZ-BORDER-RADIUS: 16PX;BORDER-RADIUS:16PX;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;BOX-SHADOW:INSET 0 1PX 0 0 #64A9F2, 0 1PX 2PX 0 #B3B3B3;COLOR:#FFF;DISPLAY:INLINE-BLOCK;FONT-SIZE:11PX;FONT-WEIGHT:400;LINE-HEIGHT: 1;BACKGROUND-COLOR:#4294F0;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#4294F0,#0156FE);TEXT-ALIGN:CENTER;TEXT-DECORATION:NONE;TEXT-SHADOW:0 -1PX 1PX #2762BF;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;BORDER-COLOR:#3371B2 #2457A3 #164297;PADDING:5PX 16PX}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2:HOVER{BORDER:1PX SOLID #2062A7;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #519CF0;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #519CF0;BOX- SHADOW:INSET 0 1PX 0 0 #519CF0;CURSOR:POINTER;BACKGROUND-COLOR:#2D88EE;BACKGROUND-IMAGE:LINEAR-GRADIENT(TOP,#2D88EE,#1554CE);TEXT-SHADOW: 0 -1PX 1PX #134FAF;-WEBKIT-BACKGROUND-CLIP:PADDING-BOX;BORDER-COLOR:#2062A7 #0E479A #01318E}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-2:ACTIVE{BACKGROUND:#226EDD;BORDER:1PX SOLID #0D3C8C;BORDER-BOTTOM:1PX SOLID #062D8D;-WEBKIT-BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;-MOZ-BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;BOX-SHADOW:INSET 0 0 6PX 3PX #0C44B8, 0 1PX 0 0 #FFF;TEXT-SHADOW: 0 -1PX 1PX #1A52AA}SECTION#BUTTONS SECTION.DEMO BUTTON.EXAMPLE-3{BORDER:1PX SOLID #8A0000;BORDER-BOTTOM:1PX SOLID #810000;-WEBKIT-BORDER- RADIUS:5PX;-MOZ-BORDER-RADIUS:5PX;BORDER-RADIUS:5PX;-WEBKIT-BOX-SHADOW:INSET 0 1PX 0 0 #FF1D0C;-MOZ-BOX-SHADOW:INSET 0 1PX 0 0 #FF1D0C;BOX-
  20. “Vendor prefixes are polluting our stylesheets...” —Albert Einstein

  21. "Nothing will benefit human health and increase chances of survival

    for life on earth as much as the evolution of cascading style sheets.” —Albert Einstein
  22. PAST ➞ PRESENT⇢ FUTURE CSS 2.1 CSS 3 CSS 3

    CSS 4 CSS 1 CSS 2 CSS 2.1
  23. CSS 4 the future of the future!

  24. BRIDGING THE GAP BETWEEN THE PRESENT AND THE FUTURE

  25. CSS 2.1 ⇢ CSS 3 ⇢CSS 4 „ You are

    here
  26. FRAMEWORKS

  27. None
  28. None
  29. METAFRAMEWORKS

  30. “that’s so meta, bro”

  31. PREPROCESSORS

  32. SASS

  33. SASS

  34. SASS

  35. MANAGE COMPLEXITY, STAY DRY, PRODUCTIVITY

  36. VARIABLES $column: 200px; $delay: 0.05s; div.container { width: $column; transition-delay:

    $delay; } Input Input
  37. VARIABLES div.container { width: 200px; transition-delay: 0.05s; } Output Output

  38. NESTING header { margin-top: 40px; h1.logo { background: url(image.png); }

    } Input Input
  39. NESTING header { margin-top: 40px; } header h1.logo { background:

    url(image.png); } Output Output
  40. MIXINS @mixin border-radius($radii) { -webkit-border-radius: $radii; -moz-border-radius: $radii; border-radius: $radii;

    } header { @include border-radius(5px); } Input Input
  41. MIXINS header { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }

    Output Output
  42. INHERITANCE .blog-header { border: 1px solid gray; } header {

    @extend .blog-header; } Input Input
  43. INHERITANCE .blog-header, header { border: 1px solid gray; } Output

    Output
  44. PARTIALS @import “header”; @import “body”; @import “footer”; Input Input

  45. OPERATORS Equality == != Number + - * / %

    Relational < > <= >= Boolean and or not
  46. AND MORE! Color Functions darken (#color, %percent) lighten (#color, %percent)

    saturate(#color, %percent) etc. Control Directives @if @for @each @while
  47. BOURBON http://thoughtbot.com/bourbon

  48. BOURBON

  49. animations appearance background-image background-size border-image border-radius box-shadow box-sizing columns flex-box

    inline-block linear-gradient radial-gradient transform transition user-select BOURBON MIXINS
  50. flex-grid golden-ratio grid-width linear-gradient modular-scale radial-gradient shade tint BOURBON FUNCTIONS

  51. button clearfix hide-text HTML5 Inputs $all-text-inputs font-family $georgia $helvetica $lucida-grande

    $monospace $verdana timing-functions $ease-in-* $ease-out-* $ease-in-out-* * = quad, cubic, quart, quint, sine, expo, circ, back BOURBON ADDONS
  52. div { @include border-radius(10px); @include box-shadow(0 2px 4px black); }

    MIXINS Input Input
  53. div { -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 0

    2px 4px black; -moz-box-shadow: 0 2px 4px black; box-shadow: 0 2px 4px black; } MIXINS Output Output
  54. FUNCTIONS Input Input

  55. $fg-column: 60px; // Column Width $fg-gutter: 25px; // Gutter Width

    $fg-max-columns: 12; // Total Columns for main container div { width: flex-grid( 4 ); // 30.882353%; margin-left: flex-gutter( 12 );// 2.45098%; p { width: flex-grid( 2, 4 ); // 46.031746%; margin: flex-gutter( 4 ); // 7.936508%; } blockquote { width: flex-grid( 2, 4 ); // 46.031746%; } }
  56. button { @include button; @include button(pill); @include button(shiny, #ff0000); }

    ADDONS Input Input
  57. ADDONS Output Output

  58. CLEAN CODEBASE = STAYING DRY

  59. SEPARATION OF PRESENTATION AND CONTENT

  60. .rounded { @include border-radius(4px); border: 1px solid black; } .shadow

    { @include box-shadow(0 2px 4px black); background: purple; }
  61. <aside class=”rounded shadow”> <!-- content --> </aside> OOCSS

  62. aside { @extend .rounded; @extend .shadow; } SASS

  63. SMACSS Scaleable and Modular Architecture for CSS

  64. BE A SASS ARCHITECT

  65. _base.scss _base-variables.scss _base-extends.scss _base-mixins.scss _base-mobile.scss _shared-header.scss _shared-sidebar.scss _shared-footer.scss _home.scss _about.scss

    BASE STYLES SHARED MODULES INDIVIDUAL PAGES
  66. _base.scss _base-variables.scss _base-extends.scss _base-mixins.scss _base-mobile.scss _shared-header.scss _shared-sidebar.scss _shared-footer.scss _home.scss _about.scss

    BASE STYLES SHARED MODULES INDIVIDUAL PAGES
  67. _base.scss _base-variables.scss _base-extends.scss _base-mixins.scss _base-mobile.scss _shared-header.scss _shared-sidebar.scss _shared-footer.scss _home.scss _about.scss

    BASE STYLES SHARED MODULES INDIVIDUAL PAGES
  68. _base.scss _base-variables.scss _base-extends.scss _base-mixins.scss _base-mobile.scss _shared-header.scss _shared-sidebar.scss _shared-footer.scss _home.scss _about.scss

    BASE STYLES SHARED MODULES INDIVIDUAL PAGES
  69. SETUP A STYLE GUIDE

  70. // FONT FAMILIES $base-font-family: $helvetica; $base-font-family-alt: $georgia; // FONT COLORS

    $base-font-color: hsl(0, 0%, 20%); $base-font-color-alt: hsl(0, 0%, 35%); $base-font-color-alt2: hsl(0, 0%, 45%); $base-font-color-alt3: hsl(0, 0%, 67%); // FONT SIZES $base-font-size: 13px; $base-font-size-alt: 15px; $base-font-size-alt2: 17px; // BACKGROUND COLORS $base-background-dark: hsl(0, 0%, 23%); $base-background-dark-alt: darken($base-background-dark, 5%); $base-background-light: hsl(0, 0%, 86%); // BORDERS $base-border-color: hsl(0, 0%, 20%); // Black $base-border-color-alt3: hsl(0, 0%, 75%); // Gray Light _BASE-VARIABLES.SCSS
  71. IDENTIFY REPEATING VISUAL PATTERNS

  72. REFACTOR & EXTRACT

  73. li:nth-child( 1 ) { @include animation-delay( 0.05s );} li:nth-child( 2

    ) { @include animation-delay( 0.1s );} li:nth-child( 3 ) { @include animation-delay( 0.15s );} ... li:nth-child( 20 ) { @include animation-delay( 1.0s );}
  74. $time: 0.05s; $delay: $time; @for $child from 1 through 20

    { li:nth-child(#{ $child }) { @include animation-delay( $delay ); } $delay: $delay + $time; }
  75. ALWAYS REMEMBER: “Don’t repeat yourself”

  76. None
  77. body.home a.home { background: orange; } body.about a.about { background:

    orange; } body.contact a.contact { background: orange; }
  78. $body-classes: home, about, contact; @each $body-class in $body-classes { body.#{$body-class}

    a.#{$body-class} { background: orange; } } }
  79. ASK YOURSELF: “Is this DRY?”

  80. $icons: image, audio, video; @each $icon in $icons { div.#{

    $icon }::before { content: url('#{ $icon }-64.png');} aside { a.#{ $icon }::before { content: url('#{ $icon }-32.png');} li a.#{ $icon }::before { content: url('#{ $icon }-16.png');} } }
  81. $icons: image, audio, video; @each $icon in $icons { div.#{

    $icon }::before { content: url('#{ $icon }-64.png');} aside { a.#{ $icon }::before { content: url('#{ $icon }-32.png');} li a.#{ $icon }::before { content: url('#{ $icon }-16.png');} } }
  82. $icons: image, audio, video; @each $icon in $icons { div.audio::before

    { content: url('audio-64.png');} aside { a.audio::before { content: url('audio-32.png');} li a.audio::before { content: url('audio-16.png');} } }
  83. div.audio::before { content: url('audio-64.png'); } aside a.audio::before { content: url('audio-32.png');

    } aside li a.audio::before { content: url('audio-16.png'); }
  84. $icons: image, audio, video, pdf; @each $icon in $icons {

    div.#{ $icon }::before { content: url('#{ $icon }-64.png');} aside { a.#{ $icon }::before { content: url('#{ $icon }-32.png');} li a.#{ $icon }::before { content: url('#{ $icon }-16.png');} } }
  85. KEY POINTS •Use Variables, Mixins, Extends •Setup a Styleguide •Identify

    repeating patterns •Refactor & Extract
  86. SASS IS A STEPPINGSTONE

  87. COMING SOON... •Nesting http://dev.w3.org/csswg/css3-hierarchies/ •Variables http://dev.w3.org/csswg/css-variables/ •Math - calc(*) function

    http://www.w3.org/TR/css3-values/#calc •Mixins? http://www.xanthir.com/blog/b49w0
  88. THANK YOU! @PHILLAPIER DESIGNER THOUGHTBOT

  89. QUESTIONS?