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

CSS preprocessors for the best of both worlds (From the Front 2014)

CSS preprocessors for the best of both worlds (From the Front 2014)

While purists propagate to not mix content structure (HTML), presentation (CSS) and behavior (JavaScript) layers for the reason of maintainability, concepts like OOCSS aim at the same goal, but from a different angle: reusable CSS code, at the expense of bloated, presentational mark-up, violating the separation of concerns. Can’t we have both, clean mark-up and reusable CSS? The benefits of both approaches without the drawbacks?
Yes, we can. This talk shows how to take the OO concept out of the HTML and put it where it belongs to: into the style sheet. Not directly into the CSS though, but into an intermediate layer provided by a CSS preprocessor like Sass.
Like Ogers and onions, concepts have layers. Unlike Ogers and onions, they don’t always stink, but eventually lead to the best of both worlds.

Video: https://www.youtube.com/watch?v=ot-LoU0MGb0

Gunnar Bittersmann

September 18, 2014
Tweet

More Decks by Gunnar Bittersmann

Other Decks in Programming

Transcript

  1. OF BOTH WORLDS
    CSS PREPROCESSORS

    View full-size slide

  2. CSS PREPROCESSORS

    View full-size slide

  3. OF BOTH WORLDS

    View full-size slide

  4. OUT OF YOUR BEANS
    COFFEE GRINDERS
    98 € PICK
    Peugeot
    Coffee grinder
    76 € PICK
    Kalita
    Coffee grinder
    54 € PICK
    Heyde
    Coffee grinder

    View full-size slide










  5. Pick me!



    View full-size slide


  6. .product-list { … }
    .product-item { … }
    .product-image { … }
    .product-brand { … }
    .product-model { … }
    .product-description { … }
    .product-price { … }
    .btn { … }
    .btn-cta { … }

    View full-size slide

  7. OUT OF YOUR BEANS
    COFFEE GRINDERS
    BUY
    Peugeot Coffee grinder
    Kalita Coffee grinder
    98 €
    76 €
    In your basket:
    total amount 174 €

    View full-size slide














  8. View full-size slide


  9. .product-list { … }
    .product-item { … }
    .product-image { … }
    .product-brand { … }
    .product-model { … }
    .product-description { … }
    .product-price { … }
    .btn { … }
    .btn-cta { … }
    .checkout-list { … }
    .checkout-item { … }
    .checkout-image { … }
    .checkout-brand { … }
    .checkout-model { … }
    .checkout-description { … }
    .checkout-price { … }

    View full-size slide










  10. Pick me!



    View full-size slide














  11. View full-size slide


  12. #page-products .product-list { … }
    #page-products .product-list li { … }
    #page-products .product-list .product-image { … }
    #page-products .product-list .brand { … }
    #page-products .product-list .model { … }
    #page-products .product-list .description { … }
    #page-products .product-list .price { … }
    #page-products .product-list button { … }

    #page-checkout .product-list { … }
    #page-checkout .product-list li { … }
    #page-checkout .product-list .product-image { … }
    #page-checkout .product-list .brand { … }
    #page-checkout .product-list .model { … }
    #page-checkout .product-list .description { … }
    #page-checkout .product-list .price { … }

    View full-size slide


  13. #page-products
    {

    .product-list
    {


    li { … }
    .product-image { … }
    .brand { … }
    .model { … }
    .description { … }
    .price { … }
    button { … }
    }
    }
    nesting

    View full-size slide


  14. #page-checkout
    {

    .product-list
    {


    li { … }
    .product-image { … }
    .brand { … }
    .model { … }
    .description { … }
    .price { … }

    }
    }
    nesting

    View full-size slide






  15. @import "_page-products";
    @import "_page-checkout";


    modularization

    View full-size slide






  16. @import "_page-products";
    @import "_page-checkout";


    modularization

    @import "_colors";
    @import "_type";
    @import "_image-replacement";
    @import "_page-layout";

    View full-size slide

  17. Atomic design (Brad Frost)

    View full-size slide

  18. Atomic design (Brad Frost)
    ATOMS MOLECULES ORGANISMS TEMPLATES PAGES

    View full-size slide

  19. no classes!
    Look ma,

    View full-size slide















  20. Pick me!



    View full-size slide


  21. #page-products
    {

    .product-list
    {


    li { … }
    [property="image"] { … }
    [property="brand"] { … }
    [property="model"] { … }
    [property="description"] { … }
    [property="price"] { … }
    button { … }
    }
    }

    View full-size slide

  22. One more cup of coffee, please!

    >One more cup of coffee, please!

    View full-size slide

  23. ONE MORE CUP OF COFFEE, PLEASE!

    One more cup of coffee, please!
    .uppercase { text-transform: uppercase }

    View full-size slide

  24. one more cup of coffee, please!

    One more cup of coffee, please!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }

    View full-size slide

  25. UN’ ALTRA TAZZA DI CAFFÈ, PER FAVORE!

    Un’ altra tazza di caffè, per favore!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }

    View full-size slide

  26. un’ altra tazza di caffè, per favore!

    Un’ altra tazza di caffè, per favore!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }

    View full-size slide

  27. NOCH EIN TÄSSCHEN KAFFEE, BITTE!

    Noch ein Tässchen Kaffee, bitte!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }

    View full-size slide

  28. noch ein tässchen kaffee, bitte!

    Noch ein Tässchen Kaffee, bitte!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }

    View full-size slide

  29. Noch ein Tässchen Kaffee, bitte!

    Noch ein Tässchen Kaffee, bitte!
    .uppercase { text-transform: uppercase }
    .lowercase { text-transform: lowercase }
    .lowercase:lang(de) { text-transform: none }
    ✘  

    View full-size slide

  30. PRESENTATIONAL
    MARKUP

    View full-size slide

  31. Noch ein Tässchen Kaffee, bitte!

    >Noch ein Tässchen Kaffee, bitte!

    h1 { text-transform: lowercase }
    h1:lang(de) { text-transform: none }
    ✔  

    View full-size slide

  32. QA'VIN LATLH TU'LUM HINOBNES!

    qa'vIn latlh tu'lum HInobneS!

    h1 { text-transform: uppercase }

    View full-size slide

  33. qa'vin latlh tu'lum hinobnes!

    qa'vIn latlh tu'lum HInobneS!

    h1 { text-transform: lowercase }

    View full-size slide

  34. qa'vIn latlh tu'lum HInobneS!

    qa'vIn latlh tu'lum HInobneS!

    h1 { text-transform: lowercase }
    :lang(tlh) { text-transform: none !important}
    ✔  

    View full-size slide




  35. .hidden { display: none }

    View full-size slide




  36. .hidden { display: none !important }

    View full-size slide




  37. .hidden { display: none !important }
    $('#pick-me').show();
    document.querySelector('#pick-me').style.display = 'block';

    View full-size slide




  38. .hidden { display: none !important }
    $('#pick-me').show();
    document.querySelector('#pick-me').style.display = 'block';

    View full-size slide

  39. $('#pick-me').removeClass('hidden');
    document.querySelector('#pick-me').classList.remove('hidden');



    .hidden { display: none !important }

    View full-size slide


  40. $('#pick-me').removeAttr('hidden');
    document.querySelector('#pick-me').removeAttribute('hidden');

    View full-size slide


  41. $('#pick-me').removeAttr('hidden');
    document.querySelector('#pick-me').removeAttribute('hidden');
    [hidden] { display: none !important }

    View full-size slide

  42. Structure
    (HTML/DOM)
    Behavior
    (JavaScript)
    Presentation
    (CSS)

    View full-size slide

  43. Structure
    (HTML/DOM)
    Presentation
    (CSS)
    Behavior
    (JavaScript)
    Separation of concerns

    View full-size slide

  44. OOCSS
    SEND ORDER CHANGE ADDRESS
    send order
    change address
    change basket
    CHANGE BASKET

    View full-size slide

  45. SEND ORDER CHANGE ADDRESS
    send order
    change address
    change basket
    CHANGE BASKET

    View full-size slide


  46. .btn
    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }

    .btn-large
    {
    padding: 0.375em;
    font-size: 1.25rem;
    }

    .btn-small
    {
    padding: 0.25em
    font-size: 1rem;
    }

    .btn-red
    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }

    .btn-black
    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }
    Stylesheet
    OOCSS

    View full-size slide

  47. OOCSS
    Object Oriented CSS
    CSS “object”: a repeating visual pattern, which can be abstracted into an independent
    snippet of HTML, CSS, and possibly JavaScript.

    Goal: reusable code, maintainability, performance
    Principles:
    1.  Separate structure and skin
    2.  Separate container and content
    Means:
    •  class selectors
    •  no element type selectors
    •  no ID selectors
    •  no descendant combinators
    •  presentational classes in the mark-up

    View full-size slide

  48. OOCSS


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet
    class selector
    class attribute
    “CSS classes”

    View full-size slide

  49. OOCSS


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet
    class selector
    class attribute
    “CSS classes”

    View full-size slide

  50. PRESENTATIONAL
    MARKUP

    View full-size slide

  51. “CSS CLASSES”

    View full-size slide

  52. OOCSS
    Object Oriented CSS
    CSS “object”: a repeating visual pattern, which can be abstracted into an independent
    snippet of HTML, CSS, and possibly JavaScript.

    Goal: reusable code, maintainability, performance
    Principles:
    1.  Separate structure and skin
    2.  Separate container and content
    Means:
    •  class selectors
    •  no element type selectors
    •  no ID selectors
    •  no descendant combinators
    •  presentational classes in the mark-up

    View full-size slide

  53. OOCSS
    Pros
    •  presentational markup
    •  bigger HTML files
    •  reusable code units
    •  smaller CSS file
    •  selector specificity
    •  selector performance
    Cons

    View full-size slide

  54. OOCSS
    Pros
    •  presentational markup
    •  bigger HTML files
    •  reusable code units
    •  selector specificity
    •  selector performance
    Cons

    View full-size slide

  55. OOCSS
    Pros
    •  presentational markup
    •  bigger HTML files
    •  reusable code units
    •  selector performance
    Cons

    View full-size slide

  56. OOCSS
    Pros
    •  presentational markup
    •  bigger HTML files
    •  reusable code units
    Cons

    View full-size slide

  57. OOCSS


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet

    View full-size slide



  58. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet

    View full-size slide



  59. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet

    View full-size slide



  60. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }










    {
    @include btn;
    @include btn-large;
    @include btn-red;
    }


    {
    @include btn;
    @include btn-small;
    @include btn-black;
    }

    @mixin btn







    @mixin btn-large





    @mixin btn-small





    @mixin btn-red





    @mixin btn-black









    [type="submit"]






    [type="button"]
    mixins

    View full-size slide



  61. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }










    {
    @include btn;
    @include btn-large;
    @include btn-red;
    }


    {
    @include btn;
    @include btn-small;
    @include btn-black;
    }

    @mixin btn







    @mixin btn-large





    @mixin btn-small





    @mixin btn-red





    @mixin btn-black









    [type="submit"]






    [type="button"]
    send order
    change address
    change basket
    mixins

    View full-size slide



  62. [type="submit"]
    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;

    padding: 0.375em;
    font-size: 1.25rem;

    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }

    [type="button"]
    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;

    padding: 0.25em;
    font-size: 1rem;

    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }










    {
    @include btn;
    @include btn-large;
    @include btn-red;
    }


    {
    @include btn;
    @include btn-small;
    @include btn-black;
    }









    [type="submit"]






    [type="button"]

    View full-size slide


  63. .btn







    .btn-large





    .btn-small





    .btn-red





    .btn-black


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }
















    [type="button"]









    [type="submit"]
    extends










    {
    @extend .btn;
    @extend .btn-large;
    @extend .btn-red;
    }


    {
    @extend .btn;
    @extend .btn-small;
    @extend .btn-black;
    }

    View full-size slide


  64. .btn







    .btn-large





    .btn-small





    .btn-red





    .btn-black


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }
















    [type="button"]









    [type="submit"]
    extends










    {
    @extend .btn;
    @extend .btn-large;
    @extend .btn-red;
    }


    {
    @extend .btn;
    @extend .btn-small;
    @extend .btn-black;
    }

    , [type="submit"], [type="button"]







    , [type="submit"]





    , [type="button"]





    , [type="submit"]





    , [type="button"]

    View full-size slide


  65. .btn







    .btn-large





    .btn-small





    .btn-red





    .btn-black


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }
















    [type="button"]









    [type="submit"]
    extends










    {
    @extend .btn;
    @extend .btn-large;
    @extend .btn-red;
    }


    {
    @extend .btn;
    @extend .btn-small;
    @extend .btn-black;
    }

    , [type="submit"], [type="button"]







    , [type="submit"]





    , [type="button"]





    , [type="submit"]





    , [type="button"]
    send order
    change address
    change basket

    View full-size slide











  66. {
    @extend %btn;
    @extend %btn-large;
    @extend %btn-red;
    }


    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-black;
    }

    %btn







    %btn-large





    %btn-small





    %btn-red





    %btn-black


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }
















    [type="button"]









    [type="submit"]









    [type="submit"]
    placeholders

    View full-size slide



  67. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    [type="submit"], [type="button"]







    [type="submit"]





    [type="button"]





    [type="submit"]





    [type="button"]










    {
    @extend %btn;
    @extend %btn-large;
    @extend %btn-red;
    }


    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-black;
    }
















    [type="button"]









    [type="submit"]









    [type="submit"]
    placeholders

    View full-size slide



  68. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    [type="submit"], [type="button"]







    [type="submit"]





    [type="button"]





    [type="submit"]





    [type="button"]










    {
    @extend %btn;
    @extend %btn-large;
    @extend %btn-red;
    }


    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-black;
    }
















    [type="button"]









    [type="submit"]









    [type="submit"]
    placeholders

    View full-size slide



  69. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    %btn







    %btn-large





    %btn-small





    %btn-red





    %btn-black






















    Markup CSS
    Sass

    View full-size slide


  70. %btn







    %btn-large





    %btn-small





    %btn-red





    %btn-black























    #page-other [type="submit"]
    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-red;
    }










    {
    @extend %btn;
    @extend %btn-large;
    @extend %btn-red;
    }


    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-black;
    }









    #page-checkout






    #page-checkout


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }









    [type="submit"]






    [type="button"]

    View full-size slide

  71. SEND ORDER CHANGE ADDRESS
    send order
    change address
    change basket
    CHANGE BASKET

    View full-size slide









  72. #ctrl-send-order






    #ctrl-change-address,
    #ctrl-change-basket









    {
    @extend %btn;
    @extend %btn-large;
    @extend %btn-red;
    }



    {
    @extend %btn;
    @extend %btn-small;
    @extend %btn-black;
    }


    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    %btn







    %btn-large





    %btn-small





    %btn-red





    %btn-black

    View full-size slide


  73. @mixin btn
    {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }

    %btn
    {
    @include btn;
    }


    @mixin %btn-large
    {
    padding: 0.375em;
    font-size: 1.25rem;
    }

    %btn-large
    {
    @include btn-large;
    }


    mixins and extends

    View full-size slide

  74. nesting
    modularization
    mixins
    extends
    placeholders
    OOSass

    View full-size slide

  75. PRESENTATIONAL
    MARKUP

    View full-size slide

  76. Structure
    (HTML/DOM)
    Presentation
    (CSS)
    Behavior
    (JavaScript)
    Separation of concerns

    View full-size slide



  77. {
    min-width: 8rem;
    font-family: "League Gothic";
    text-align: center;
    border-radius: 0.375em;
    }


    {
    padding: 0.375em;
    font-size: 1.25rem;
    }


    {
    padding: 0.25em
    font-size: 1rem;
    }


    {
    background-color: hsl(2, 42%, 39%);
    background-image: linear-gradient(…);
    }


    {
    background-color: hsl(0, 0%, 20%);
    background-image: linear-gradient(…);
    }

    btn







    btn-large





    btn-small





    btn-red





    btn-black






















    Markup Stylesheet

    View full-size slide

  78. WHICH SIDE
    ARE YOU ON?

    View full-size slide