$30 off During Our Annual Pro Sale. View Details »

CSS as a Service: Maintaining Style

Shay Howe
October 02, 2014

CSS as a Service: Maintaining Style

We often build multiple websites and applications that share the same styles across multiple code bases (style guides/pattern libraries). Maintaining these styles becomes quite a task, and causes increasing frustration overtime. Fortunately it doesn’t have to be this way.

Within this talk we’ll cover a service-oriented architecture approach to writing HTML and CSS, including Sass, and keeping our code modular and performant. Geared towards designers and front-end developers, we’ll discuss at how to best structure and write front-end code for maintainability and reuse, as well as how to properly package these styles to be used within different development environments. Consistency shouldn’t take a back seat to maintainability, and this talk covers how to have the best of both worlds.

Shay Howe

October 02, 2014
Tweet

More Decks by Shay Howe

Other Decks in Technology

Transcript

  1. CSS as a Service
    Maintaining Style
    Shay Howe
    @shayhowe
    learn.shayhowe.com

    View Slide

  2. CSS as a Service @shayhowe
    A ton, really…
    We build a lot of websites.

    View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. We can do better.

    View Slide

  10. CSS as a Service @shayhowe

    View Slide

  11. CSS as a Service @shayhowe
    Service-Oriented
    Architecture
    (SOA)

    View Slide

  12. CSS as a Service @shayhowe

    View Slide

  13. CSS as a Service @shayhowe

    View Slide

  14. CSS as a Service @shayhowe

    View Slide

  15. CSS as a Service @shayhowe
    Style as a Service
    • CSS & Sass (Variables, mixins, utilities, the works!)
    • JS & CoffeeScript modules
    • Images
    • Fonts
    • Miscellaneous assets

    View Slide

  16. CSS as a Service @shayhowe
    Rolodex
    github.com/bellycard/rolodex

    View Slide

  17. CSS as a Service @shayhowe
    Disclaimer:
    My Way ≠ Highway

    View Slide

  18. CSS as a Service @shayhowe
    Architecture

    View Slide

  19. $  bundle  install  rolodex
    ~/code

    View Slide

  20. CSS as a Service @shayhowe
    Organization
    • 25 Sass files
    • 7 SCSS files
    • 6 folders

    View Slide

  21. /vendor/assets/stylesheets
    › rolodex
    › base
    › components
    › settings
     › mixins
     › utilities
     › variables
      _settings.sass
    rolodex.css.sass

    View Slide

  22. CSS as a Service @shayhowe
    Process

    View Slide

  23. CSS as a Service @shayhowe
    Parallel Development
    • Work in the context of real content
    • Application ➞ Toolkit ➞ Style guide

    View Slide

  24. CSS as a Service @shayhowe
    Home Page Toolkit Style Guide

    View Slide

  25. CSS as a Service @shayhowe
    Connect the Dots
    • Add toolkit dependency
    • Import associated file(s)

    View Slide

  26. #  Development
    gem  'rolodex',  path:  '~/code/rolodex'
    Gemfile

    View Slide

  27. #  Production
    gem  'rolodex',  '2.0.0'
    Gemfile

    View Slide

  28. app.css.sass
    @import  rolodex

    View Slide

  29. CSS as a Service @shayhowe
    Home Page Toolkit Style Guide
    @import  rolodex @import  rolodex
    rolodex.css.sass

    View Slide

  30. CSS as a Service @shayhowe
    Groundwork
    • Set the stage for what will be
    • Add baseline of default styles

    View Slide

  31. rolodex.css.sass
    //  Base
    @import  rolodex/base/layout
    @import  rolodex/base/typography
    //  Components
    @import  rolodex/components/forms
    @import  rolodex/components/media
    @import  rolodex/components/tables

    View Slide

  32. CSS as a Service @shayhowe
    Provide Settings
    • Document what is known (Colors, grid, typography)
    • Add variables & maps
    • Define mixins & utilities

    View Slide

  33. /settings/_settings.sass
    //  Variables
    @import  variables/...
    //  Mixins
    @import  mixins/...
    //  Utilities
    @import  utilities/...

    View Slide

  34. rolodex.css.sass
    //  Settings
    @import  rolodex/settings/settings
    //  Base
    ...
    //  Components
    ...

    View Slide

  35. CSS as a Service @shayhowe
    Add Components
    • Work through additional components
    • Add components as needed, not as wanted

    View Slide

  36. rolodex.css.sass
    //  Components
    @import  rolodex/components/alerts
    @import  rolodex/components/buttons
    @import  rolodex/components/dropdowns
    @import  rolodex/components/forms
    @import  rolodex/components/media
    @import  rolodex/components/tables
    @import  rolodex/components/tooltips
    @import  rolodex/components/...

    View Slide

  37. CSS as a Service @shayhowe
    Rinse & Repeat
    • Watch for duplicate code, then refactor
    • Adjust as needed
    • Create new variables, maps, & utilities as best fit

    View Slide

  38. CSS as a Service @shayhowe
    Implementation

    View Slide

  39. CSS as a Service @shayhowe
    Single Responsibility Principle
    • Every class should have a single responsibility
    • Responsibility should be encapsulated by the class

    View Slide

  40. /_shame.sass
    .alert
    background:  #f2dede
    border-­‐radius:  10px
    color:  #b94a48
    padding:  10px  20px
    ...

    View Slide

  41. /_shame.sass
    .alert
    background:  #f2dede
    border-­‐radius:  10px
    color:  #b94a48
    padding:  10px  20px
    ...

    View Slide

  42. /components/_alerts.sass
    .alert
    border-­‐radius:  10px
    padding:  10px  20px
    .alert-­‐error
    background:  #f2dede
    color:  #b94a48
    ...

    View Slide

  43. CSS as a Service @shayhowe
    Decouple HTML & CSS
    • Remove parent container dependency
    • Allow elements to adapt

    View Slide

  44. /_shame.sass
    .feat-­‐box
    background:  #ccc
    article  .feat-­‐box
    background:  #fff

    ...

    View Slide

  45. /_shame.sass
    .feat-­‐box
    background:  #ccc
    article  .feat-­‐box
    background:  #fff

    ...

    View Slide

  46. /components/_feat-box.sass
    .feat-­‐box
    background:  #ccc
    .feat-­‐box-­‐alt
    background:  #fff

    ...

    View Slide

  47. /_shame.sass
    .feat-­‐box  h2
    color:  #f60
    font:  18px  Helvetica,  sans-­‐serif

    ...

    View Slide

  48. /_shame.sass
    .feat-­‐box  h2
    color:  #f60
    font:  18px  Helvetica,  sans-­‐serif

    ...

    View Slide

  49. /components/_typography.sass
    .h-­‐subtitle
    color:  #f60
    font:  18px  Helvetica,  sans-­‐serif

    ...

    View Slide

  50. CSS as a Service @shayhowe
    Keep Specificity Low
    • Be explicit
    • Use classes
    • Avoid nested selectors

    View Slide

  51. /_shame.sass
    #primary  #main  div.gallery
    ...
    #primary  #main  div.gallery  figure.media
    ...
    #primary  #main  div.gallery  figcaption.title
    ...

    View Slide

  52. /_shame.sass
    #primary  #main  div.gallery
    ...
    #primary  #main  div.gallery  figure.media
    ...
    #primary  #main  div.gallery  figcaption.title
    ...

    View Slide

  53. /components/_gallery.sass
    .gallery
    ...
    .gallery-­‐media
    ...
    .gallery-­‐title
       ...

    View Slide

  54. CSS as a Service @shayhowe
    Name with Care
    • Name for understanding
    • Favor functional names
    • Use a sensible pattern

    View Slide

  55. /_shame.sass
    .plan  .callout  .pr
    ...
    .plan  .callout  .pr  .un
    ...

    View Slide

  56. /_shame.sass
    .plan  .callout  .pr
    ...
    .plan  .callout  .pr  .un
    ...

    View Slide

  57. /components/_pricing.sass
    .plan  .price
    ...
    .plan  .unit
    ...

    View Slide

  58. /components/_buttons.sass
    .btn-­‐success
    ...
    .btn-­‐danger
    ...
    .btn-­‐default
    ...

    View Slide

  59. /components/_alerts.sass
    .alert-­‐success
    ...
    .alert-­‐danger
    ...
    .alert-­‐default
       ...
    /components/_buttons.sass
    .btn-­‐success
    ...
    .btn-­‐danger
    ...
    .btn-­‐default
    ...

    View Slide

  60. /components/_buttons.sass
    .btn-­‐success
    ...
    .btn-­‐danger
    ...
    .btn-­‐default
    ...
    /components/_labels.sass
    .label-­‐success
    ...
    .label-­‐danger
    ...
    .label-­‐default
    ...

    View Slide

  61. CSS as a Service @shayhowe
    Leverage Sass Maps
    • Dynamically generate styles
    • Easily write extends
    • Quickly build components

    View Slide

  62. /utilities/_typography.sass
    @each  $color,  $i  in  $colors
    .text-­‐#{$i}
    color:  $color
    /variables/_typography.scss
    $green:  #45ad60;
    $gold:    #f3ae4e;
    $red:      #cb4e52;
    $colors:  (
    $green:  success,
    $gold:    warning,
    $red:      danger
    );

    View Slide

  63. /utilities/_typography.sass
    @each  $color,  $i  in  $colors
    .text-­‐#{$i}
    color:  $color
    Compiled CSS
    .text-­‐success  {
    color:  #45ad60;
    }
    .text-­‐warning  {
    color:  #f3ae4e;
    }
    .text-­‐danger  {
    color:  #cb4e52;
    }

    View Slide

  64. /components/_alerts.sass
    @each  $alert  in  $alerts
    $kind:    nth($alert,  1)
    $color:  nth($alert,  2)
    $icon:    nth($alert,  3)
    .alert-­‐#{$kind}
    background:
    $color
    url("#{$icon}.svg")
    /variables/_alerts.scss
    $green:  #45ad60;
    $gold:    #f3ae4e;
    $red:      #cb4e52;
    $alerts:  (
    (success,  $green,  tick)
    (warning,  $gold,    info)
    (danger,    $red,      alarm)
    );

    View Slide

  65. /components/_alerts.sass
    @each  $alert  in  $alerts
    $kind:    nth($alert,  1)
    $color:  nth($alert,  2)
    $icon:    nth($alert,  3)
    .alert-­‐#{$kind}
    background:
    $color
    url("#{$icon}.svg")
    Compiled CSS
    .alert-­‐success  {
    background:
    #45ad60  url("tick.svg");
    }
    .alert-­‐warning  {
    background:
    #f3ae4e  url("info.svg");
    }
    .alert-­‐danger  {
       background:
    #cb4e52  url("alarm.svg");
    }

    View Slide

  66. CSS as a Service @shayhowe
    Compose with Sass Mixins
    • Share common groups of declarations
    • Create variables for repeated values
    • Use arguments when beneficial

    View Slide

  67. /components/_icons.sass
    .primary-­‐logo
    +ir
    background:  url("logo.svg")
    height:  30px
    width:  150px
    /mixins/_layout.sass
    =ir
    color:  transparent
    font:  0/0  a
    text-­‐shadow:  none

    View Slide

  68. /components/_icons.sass
    .primary-­‐logo
    +ir
    background:  url("logo.svg")
    height:  30px
    width:  150px
    Compiled CSS
    .primary-­‐logo  {
    color:  transparent;
    font:  0/0  a;
    text-­‐shadow:  none;
    background:  url("logo.svg");
    height:  30px;
    width:  150px;
    }

    View Slide

  69. /components/_menus.sass
    .dropdown
    +box-­‐outline(#33a9e0)
    font-­‐size:  16px
    /mixins/_layout.sass
    $white:    #fff
    $radius:  6px
    =box-­‐outline($border-­‐color)
    background-­‐color:  $white
    border-­‐color:  $border-­‐color
    border-­‐radius:  $radius

    View Slide

  70. /components/_menus.sass
    .dropdown
    +box-­‐outline(#33a9e0)
    font-­‐size:  16px
    Compiled CSS
    .dropdown  {
    background-­‐color:  #fff;
    border-­‐color:  #33a9e0;
    border-­‐radius:  6px;
    font-­‐size:  16px;
    }

    View Slide

  71. CSS as a Service @shayhowe
    Inherit Styles with Sass Extends
    • Share common declarations across related components
    • Only use placeholder extends
    • Do not chain extends

    View Slide

  72. Compiled CSS
    .avatar,
    .snapshot  {
    border-­‐radius:  50%;
    }
    .profile  .avatar,  
    .profile  .snapshot  {
    display:  block;
    }
    /_shame.sass
    .avatar
    border-­‐radius:  50%
    .snapshot
    @extend  .avatar
    .profile  .avatar
    display:  block

    View Slide

  73. Compiled CSS
    .avatar,
    .snapshot  {
    border-­‐radius:  50%;
    }
    .profile  .avatar,  
    .profile  .snapshot  {
    display:  block;
    }
    /_shame.sass
    .avatar
    border-­‐radius:  50%
    .snapshot
    @extend  .avatar
    .profile  .avatar
    display:  block

    View Slide

  74. Compiled CSS
    .profile  .avatar,  
    .snapshot  {
    border-­‐radius:  50%;
    }
    .profile  .avatar  {
    display:  block;
    }
    /extends/_media.sass
    %avatar
    border-­‐radius:  50%
    .snapshot
    @extend  %avatar
    .profile  .avatar
    @extend  %avatar
    display:  block

    View Slide

  75. CSS as a Service @shayhowe
    Favor Sass Mixins
    • Allow arguments
    • Work within media queries
    • Smaller file sizes (when gzipped)
    • Faster load times

    View Slide

  76. Extends

    View Slide

  77. Mixins

    View Slide

  78. CSS as a Service @shayhowe
    Watch Your Output
    • Test early, test often
    • Monitor speed & performance
    • Concatenate & compress files

    View Slide

  79. /shame.css
    .nav  {...}
    .nav  .nav-­‐list  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a:hover,
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a:focus  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  span  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  span.count  {...}

    View Slide

  80. /shame.css
    .nav  {...}
    .nav  .nav-­‐list  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a:hover,
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a:focus  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  span  {...}
    .nav  .nav-­‐list  .nav-­‐list-­‐item  a  span.count  {...}

    View Slide

  81. CSS as a Service @shayhowe
    Measure Your Improvements
    • Identify a baseline
    • Select a few KPIs (File size, # of rulesets, selectors, unique values)
    • Look into StyleStats, CSSCSS, CSS Lint & WebPagetest

    View Slide

  82. CSS as a Service @shayhowe
    File size 202.9kb 109.4kb 46.08%
    Rules 2,420 996 58.84%
    Selectors 3,560 1,271 64.3%
    Unique font sizes 36 23 36.11%
    Unique colors 141 42 70.21%
    !important keywords 126 0 100.00%
    color properties 335 169 52.39%
    font-­‐size properties 204 199 2.45%
    Style as a Service @shayhowe
    v1 v2 (Rolodex) Difference

    View Slide

  83. CSS as a Service @shayhowe
    Unique colors 141 42 70.21%
    !important keywords 126 0 100.00%
    color properties 335 169 52.39%
    font-­‐size properties 204 199 2.45%
    float properties 80 42 47.50%
    display properties 295 87 70.51%
    margin properties 177 100 43.50%
    padding properties 239 152 36.40%
    Style as a Service @shayhowe
    v1 v2 (Rolodex) Difference

    View Slide

  84. CSS as a Service @shayhowe
    Final Thoughts

    View Slide

  85. CSS as a Service @shayhowe
    Study the Documentation
    • Dig into the CSS & Sass documentation
    • Learn your environment

    View Slide

  86. /components/_networks.sass
    $networks:  (facebook:  #3b5998,  twitter:  #55acee)
    @each  $network,  $color  in  $networks
    .network-­‐#{$network}
    background-­‐color:  $color
    @if  index(map-­‐keys($networks),  $network)  !=  1
    background-­‐position:
    (-­‐24px  *  (index(map-­‐keys($networks),  $network)  -­‐  1))  0

    View Slide

  87. Compiled CSS
    .network-­‐facebook  {
    background-­‐color:  #3b5998;
    }
    .network-­‐twitter  {
    background-­‐color:  #55acee;
    background-­‐position:  -­‐24px  0;
    }

    View Slide

  88. CSS as a Service @shayhowe
    Don’t Over Think
    • Write code out the long way, then refactor
    • Rename, rewrite, & refactor willing
    • Document everything!

    View Slide

  89. View Slide

  90. CSS as a Service @shayhowe
    Work Together
    • Seek help & get feedback
    • Open the style framework to everyone

    View Slide

  91. View Slide

  92. Enjoy your work!

    View Slide

  93. CSS as a Service @shayhowe
    Thank You!
    @shayhowe
    learn.shayhowe.com
    bit.ly/sxsw-css

    View Slide