Building a CSS Foundation

Building a CSS Foundation

Code duplication, bloat and specificity battles are very common problems when sites grow, and they can spell disaster for site performance. In this session we will cover code organization and naming conventions to help your site grow. Attendees will learn how to build sites with the most reusable CSS possible.

E4df4a30f000a225df7114e4940944e7?s=128

jakefolio

March 01, 2013
Tweet

Transcript

  1. Building a CSS Foundation Jake Smith CONFOO 2013

  2. Jake Smith jakefolio http://jakefolio.com me@jakefolio.com

  3. http://bit.ly/VuP5d5

  4. None
  5. Constant Evaluation & Self-Loathing

  6. Specificity Kills

  7. Specificity is hard, especially to pronounce!

  8. None
  9. Do NOT carpet bomb your elements

  10. /** * You wouldn't do this */ div { color:

    #ccc; padding: 1em 2em; }
  11. /** * You wouldn't do this */ div { color:

    #ccc; padding: 1em 2em; } /** * So why would you do this */ header { color: #ccc; padding: 1em 2em; }
  12. /** * Better solutions */ #header {} .header {} body

    > header {} /** * You wouldn't do this */ div { color: #ccc; padding: 1em 2em; } /** * So why would you do this */ header { color: #ccc; padding: 1em 2em; }
  13. /** * Well... */ #header ul { color: #ccc; padding:

    1em 2em; }
  14. /** * Well... */ #header ul { color: #ccc; padding:

    1em 2em; } /** * What?? */ #sidebar div { border-bottom: 1px; }
  15. /** * WAT */ .content p { font-size: 14px; }

    /** * Well... */ #header ul { color: #ccc; padding: 1em 2em; } /** * What?? */ #sidebar div { border-bottom: 1px; }
  16. CSS is easy, naming stuff is hard!

  17. #sidebar div {} GUESS THAT ELEMENT!

  18. #sidebar div {} GUESS THAT ELEMENT! .promo-box {}

  19. #sidebar div {} header ul {} GUESS THAT ELEMENT! .promo-box

    {}
  20. #sidebar div {} header ul {} GUESS THAT ELEMENT! .promo-box

    {} .nav-main {}
  21. #sidebar div {} h2 span {} header ul {} GUESS

    THAT ELEMENT! .promo-box {} .nav-main {}
  22. #sidebar div {} h2 span {} header ul {} GUESS

    THAT ELEMENT! .promo-box {} .nav-main {} .tagline {}
  23. Clear Intent is the Goal

  24. Do NOT over qualify your declaration

  25. /** * Stop strangling your fellow developer */ ul.nav-primary {}

    div#header {} body.two-col {}
  26. Do NOT let your CSS dictate your HTML structure

  27. /** * FREEDOM! */ .nav-primary {} #header {} .two-col {}

  28. Let’s make specificity easy

  29. Avoid using IDs*

  30. Modular Development

  31. Stop developing pages and start developing systems

  32. History (Brief) of OOCSS

  33. .media { display: block; @extend .cf; } .media-img { float:

    left; margin-right: $base-spacing-unit; } /** * Reversed image location (right instead of left). */ .media-img--rev { float: right; margin-left: $base-spacing-unit; } .media-img img, .media-img--rev img { display: block; } .media-body { overflow: hidden; } .media .media--rev https://github.com/csswizardry/inuit.css/blob/master/inuit.css/objects/_media.scss
  34. None
  35. Module/Object

  36. Separate structure from style

  37. /** * Base Button Object * @tags ^button * @format

    * <a href="#" class="btn">Register</a> * <button class="btn">Register</button> * <input type="submit" class="btn" value="Register"> */ .btn { border: none; display: inline-block; margin: 0; padding: 0.5em; cursor: pointer; font: inherit; line-height: 1; } .btn, .btn:hover { text-decoration: none; }
  38. <div class="container"> <p><input class="btn" type="submit" value="Subscribe"></p> <p><a href="#" class="btn">Subscribe</a></p> <p><button

    class="btn" type="submit">Subscribe</button></p> </div> HTML Structure Base State
  39. /** * Button Sizes * @tags ^button * @extends btn

    */ .btn-small { font-size: 1.25em; } .btn-medium { font-size: 1.5em; } .btn-large { font-size: 2em; } .btn-xlarge { font-size: 2.5em; } /** * Primary Button Style * @tags ^button * @extends btn */ .btn-primary { box-shadow: 3px 3px 0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; -webkit-transition: box-shadow 0.5s; transition: box-shadow 0.5s; } .btn-primary:hover { box-shadow: 1px 1px 0 rgba(0,0,0,0.25); }
  40. <div class="container"> <p><input class="btn btn-large" type="submit" value="Subscribe"></p> <p><a href="#" class="btn

    btn-large">Subscribe</a></p> <p><button class="btn btn-large" type="submit">Subscribe</button></p> </div> HTML Structure Change the Size
  41. <div class="container"> <p><input class="btn btn-large btn-primary" type="submit" value="Subscribe"></p> <p><a href="#"

    class="btn btn-large btn-primary">Subscribe</a></p> <p><button class="btn btn-large btn-primary" type="submit">Subscribe</button></p> </div> HTML Structure Add Styling
  42. btn btn-primary Sub-module module element btn-large Sub-module sizing styling

  43. http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  44. .featured-posts http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  45. .featured-posts .recent-posts http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  46. .featured-posts .recent-posts .active- members http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  47. /* ============================================================ Media Object (OOCSS) ============================================================ */ .media { *zoom:

    1; } .media > .media-image { display: block; float: left; margin-right: 10px; } .l-grid .media-image { float: none; margin: 0; } .media > .media-body { color: #ccc; font-size: 0.8em; padding: 5px 10px; }
  48. /* ============================================================ Media List ============================================================ */ /** * List of

    media objects * @tags ^list ^media */ .media-list { margin-left: 0; list-style: none; } .media-list > .media-item, .media-list > li { clear: both; display: block; margin: 0.75em 0; background: #fff; } .l-grid .media-item, .l-grid li { box-shadow: 0 0 5px rgba(0, 0, 0, 0.6); border: 3px solid #fff; display: inline-block; margin: 0.75em; } /** * Featured Articles Media List * @tags ^list ^media * @extends media-list */ .media-featured-list > .media-item, .media-featured-list > li { width: 150px; }
  49. <div class="l-grid"> <div class="media-list media-featured-list"> <div class="media media-item"> <img src="images/demo/feature1.jpg"

    class="media-image"> <section class="media-body"> <h3 class="subline">Travel</h3> </section> </div> </div> </div> <div class="l-grid"> <ul class="media-list"> <li class="media"> <img src="images/demo/profile1.jpg" class="media-image"> </li> </ul> </div> DIV Example LI Example
  50. media media-list media- featured- list l-grid Sub-module layout element module

    element
  51. http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  52. .l-grid .media-list http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  53. .l-grid .media-list .media-list http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  54. .l-grid .media-list .media-list .l-grid .media- list http://themeforest.net/item/onecommunity-buddypress-theme/3713046?WT.ac=new_item&WT.seg_1=new_item&WT.z_author=Diabolique

  55. None
  56. Context MUST NOT modify your modules

  57. Code Standard/Styles

  58. Formatting

  59. .btn-small { font-size: 1.25em; } .btn-primary { box-shadow: 3px 3px

    0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; } code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
  60. .btn-small { font-size: 1.25em; } .btn-primary { box-shadow: 3px 3px

    0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; } code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } hyphen separated class names
  61. .btn-small { font-size: 1.25em; } .btn-primary { box-shadow: 3px 3px

    0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; } code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } hyphen separated class names space between property and value
  62. .btn-small { font-size: 1.25em; } .btn-primary { box-shadow: 3px 3px

    0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; } code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } hyphen separated class names space between property and value inline only allowed when one property is present
  63. .btn-small { font-size: 1.25em; } .btn-primary { box-shadow: 3px 3px

    0 rgba(0,0,0,0.25); background: #403731; color: #fff; font-family: $fontButtonFamily; font-weight: 300; letter-spacing: 1px; text-transform: uppercase; } code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } hyphen separated class names space between property and value one selector per line inline only allowed when one property is present
  64. Declaration Order

  65. .selector { /* Positioning */ position: absolute; z-index: 10; top:

    0; left: 0; /* Display & Box Model */ display: inline-block; overflow: hidden; box-sizing: border-box; width: 100px; height: 100px; padding: 10px; margin: 10px; /* Other (styling and typography) */ background: #000; color: #fff; font-family: sans-serif; font-size: 16px; text-align: right; /* CSS Preprocessor mixins */ .lessMixin(); @include sassMixin(); }
  66. Documentation

  67. /** * Primary site navigation * * @tags: ^lists ^navigation

    * @extends: nav * * @format: * <ul class="nav nav-main"> * <li><a href="#">Home</a></li> * <li><a href="#">About</a></li> * </ul> */ .nav-main { ! display: block; ! background: #af2518; ! font-family: $fontHeadlineFamily; ! font-weight: 700; } ! .nav-main > li > a, ! .nav-main > .nav-item > a {}
  68. Predictability & Consistency

  69. Readability & Maintainability

  70. https://github.com/necolas/idiomatic-css

  71. http://make.wordpress.org/core/handbook/coding-standards/css/

  72. Organization and Structure

  73. Abstraction and modularity is great.....until it’s not.....

  74. If it takes more than 5 seconds to figure out

    where to put something, you’ve gone too far
  75. Tools and Resources

  76. http://csslint.net/

  77. https://github.com/squizlabs/PHP_CodeSniffer

  78. 1 Naming is hard, so be clear with your styles

    In general, instead of carpet bombing your elements, shoot to kill; target them specifically and explicitly. Make sure your selector intent is accurate and targeted. - Harry Roberts, @csswizardry http://csswizardry.com/2012/07/shoot-to-kill-css-selector-intent/
  79. 2 Don’t let your styles define your HTML Structure Creates

    complexity and limits modularity
  80. 3 Small modules are easier to maintain Don’t let context

    change your module
  81. 4 Consistency and Predictability always win out This is why

    people go on about readability, clarity, simplicity, and explicitness; because they are all fundamentally characteristics of a maintainable code base. - Andy Hume, @andyhume http://www.youtube.com/watch?v=ZpFdyfs03Ug
  82. 5 Document for tomorrow’s developer This Could Be You

  83. http://bit.ly/VuP5d5 Links and Resources

  84. Questions? Concerns? Complaints?

  85. Thanks for Listening jakefolio http://jakefolio.com me@jakefolio.com Please Rate Me! https://joind.in/7990