Planes, Trains, and CSS Components

Planes, Trains, and CSS Components

The way we’re meant to be writing CSS appears to be in constant flux! What’s the safest route? Do we go for just writing vanilla CSS - is this the simplest and thus the safest? What about pre-processors like Sass or LESS? Or, do we look for more adventure with off-road vehicles like JavaScript or Web Components?

Join me as I take you on a journey through these different techniques for creating components. We’ll tackle all the bumps in the road head-on and fly straight into the eye of the storm, as we loop and swerve around development opinions.

The best thing about this journey, is we’ll see what it takes to engineer a component system for a large organisation. Using the best techniques available to us, both old and new. Ensuring styles are reusable, transferable, and easy to use across a variety of teams and products.

Fc7368fd45560e1e7401bc80684f5867?s=128

Adam Onishi

July 25, 2016
Tweet

Transcript

  1. Adam Onishi Financial Times @onishiweb Planes, trains, and CSS components

  2. FINANCIAL TIMES @onishiweb

  3. @onishiweb

  4. 1. Unify front-end styles across the FT 2. Reduce time

    spent repeating work @onishiweb
  5. Components! @onishiweb

  6. http://registry.origami.ft.com/components o-header o-table o-card

  7. http://origami.ft.com/

  8. Building components @onishiweb

  9. @onishiweb

  10. @onishiweb

  11. 1. Automobiles 2. Trains 3. Planes

  12. 1. CSS 2. CSS Modules 3. Web Components

  13. The CSS way…

  14. The current way… @onishiweb

  15. The Sass/LESS way @onishiweb

  16. The BEM way @onishiweb

  17. The SMACSS way @onishiweb

  18. The OOCSS way @onishiweb

  19. The Atomic CSS way @onishiweb

  20. @onishiweb • Naming convention • Namespacing • Reduce specificity •

    Easy to understand • Require discipline
  21. The Origami way… @onishiweb

  22. The BEM way @onishiweb

  23. Specificity must be minimised. Use BEM… Origami spec http://origami.ft.com/docs/syntax/scss/

  24. An example: @onishiweb

  25. @onishiweb

  26. <div class="o-gallery" o-gallery> <ul class="o-gallery__content"> <li class="o-gallery__slide"> <figure class="o-gallery__figure"> <img

    src="#" alt="text" class="o-gallery__image"> <figcaption class="o-gallery__caption"> This is an image caption </figcaption> </figure> </li> </ul> </div>
  27. .o-gallery__figure {} .o-gallery__figure__image {} .o-gallery__figure__caption {}

  28. .o-gallery__figure {} .o-gallery__figure__image {} .o-gallery__figure__caption {} // Better .o-gallery__figure {}

    .o-gallery__image {} .o-gallery__caption {}
  29. .o-gallery__control { position: absolute; top: 50%; width: 30px; height: 70px;

    } .o-gallery__control--left { left: 0; background-image: url(''), none; } .o-gallery__control--right { right: 0; background-image: url(''), none; }
  30. this.controlLeft = document.createElement('button'); this.controlLeft.className = 'o-gallery__control o-gallery__control-- left';

  31. Using Origami components @onishiweb

  32. @import "o-assets/main"; @import "o-colors/main"; @import "o-icons/main"; @import "o-hoverable/main"; @import "o-gallery/main";

  33. require('o-date'); require('o-header'); require('o-gallery');

  34. Alice Bartlett Origami Lead, Financial Times @alicebartlett Can’t you make

    it more like Bootstrap? Considerations for building front end systems
  35. What about HTML? @onishiweb

  36. Customisation @onishiweb

  37. /// General styling for the gallery @mixin oGallery { [...]

    } /// Styling for the gallery title @mixin oGalleryTitle { [...] }
  38. The Cascade @onishiweb

  39. The current Origami way… @onishiweb

  40. 1. CSS 2. CSS Modules 3. Web Components

  41. Remix culture

  42. @onishiweb

  43. The CSS Modules way…

  44. What is CSS Modules? @onishiweb

  45. [CSS where] all class names and animation names are scoped

    locally by default CSS Modules Spec https://github.com/css-modules/css-modules
  46. .gallery { } .wrapper { } .content { } .slide

    { }
  47. ._gallery_1rsuk_1 { } ._wrapper_1rsuk_7 { } ._content_1rsuk_13 { } ._slide_1rsuk_25

    { }
  48. Values and composes @onishiweb

  49. @value primary: red; .btn-primary { background: white; border: 1px solid

    primary; color: primary; }
  50. @value aliceblue: red; @value relative: absolute;

  51. .btn-primary { background: white; border: 1px solid red; color: red;

    } .btn-secondary { composes: btn-primary; border-color: blue; color: blue; }
  52. <button class="app__btnSecondary___3JL8l app__btnPrimary___1y7r3"></button>

  53. Truly component only CSS @onishiweb

  54. Requires a build step @onishiweb

  55. @onishiweb • Webpack • Browserify • Babel • PostCSS •

    JSPM
  56. An example: @onishiweb

  57. @onishiweb

  58. No more .html @onishiweb

  59. <div class="<%= className('styles', 'gallery') %>" o- gallery> <ul class="<%= className('styles',

    'content') %>"> <li class="<%= className('styles', 'slide') %>"> <figure class="<%= className('styles', 'figure') %>"> <img src="#" alt="#" class="<%= className('styles', 'image') %>"> <figcaption class="<%= className('styles', 'caption') %>"> This is an image caption </figcaption> </figure> </li> </ul> </div>
  60. CSS > JSON > HTML @onishiweb

  61. What about the JavaScript? @onishiweb

  62. this.controlLeft = document.createElement('button'); this.controlLeft.className = className('styles', 'control-left');

  63. Great in a JavaScript world @onishiweb

  64. Atomic CSS Modules @onishiweb

  65. .M-10 { margin: 10px; } .Fl-start { float: left; }

    .Mend-10 { margin-right: 10px; } .Fz-s { font-size: smaller; }
  66. .tabs { composes: width-100 from 'size'; composes: reset from 'list';

    composes: flex from 'display'; /* tablet and up */ composes: block from 'display/tablet'; } .item { composes: inline-block from 'display'; composes: solid top-reset right-reset bottom left-reset from 'border'; composes: top bottom from 'padding'; composes: pointer from 'cursor'; composes: ui all from 'transition'; }
  67. We decided to solve the main Atomic CSS-related problems using

    the power of CSS Modules, getting all the benefits of both solutions. Michele Bertoli https://medium.com/yplan-eng/atomic-css-modules-cb44d5993b27#.p7jtpneoh
  68. Is Origami going to use CSS Modules? @onishiweb

  69. No.

  70. First Class Styles - Mark Dalgleish Front Trends 2016 https://www.youtube.com/watch?v=KmtgJ1d4zuY

  71. The alternative way… @onishiweb

  72. Delayed 1. Automobiles 2. Trains 3.

  73. 1. CSS 2. CSS Modules 3. Web Components

  74. The Web Components way…

  75. @onishiweb • Custom elements • Shadow DOM • Templates •

    HTML imports/JavaScript modules
  76. Custom Elements @onishiweb

  77. <!-- Instead of --> <div class="o-gallery"></div> <!-- We can do

    --> <o-gallery></o-gallery>
  78. class OGallery extends HTMLElement { constructor() { super(); [...] }

    [...] } customElements.define('o-gallery', OGallery);
  79. const oGallery = document.createElement('o-gallery'); document.body.appendChild(oGallery); // Show the next slide

    oGallery.nextSlide();
  80. Templates @onishiweb

  81. <template> <div class="slides"> <div class="slide"></div> </div> <button class="control-left"></button> <button class="control-right"></button>

    </template>
  82. HTML Imports @onishiweb

  83. <link rel="import" href="o-gallery.html">

  84. JavaScript modules @onishiweb

  85. Shadow DOM

  86. This is where things get spooky and weird! Soledad Penades

    https://www.youtube.com/watch?v=2vWgJ7w3hu0
  87. @onishiweb

  88. Creating a Shadow DOM @onishiweb

  89. // Attaches a shadow-root to your element const shadow =

    this.attachShadow({mode: 'open'});
  90. // Attaches a shadow Root to your element const shadowRoot

    = this.attachShadow({mode: 'open'}); // Get the custom template, clone it const template = document.querySelector('#o-gallery'); const clone = this.importNode(template, true); // Insert it into our shadow DOM shadowRoot.appendChild(clone);
  91. Slots @onishiweb

  92. <template> <div class="container"> <slot name="slides"></slot> </div> </template>

  93. <o-gallery> <img src="/assets/img/plane.jpg" alt="Delayed plane" slot="slides"> </o-gallery>

  94. Styling web components @onishiweb

  95. <template> <style> :host { background-color: #333; } .slide { margin:

    0; } img { display: block; } .caption { color: #fff; } </style> </template>
  96. Fully encapsulated styles @onishiweb

  97. ::host and ::host-context @onishiweb

  98. ::host(.theme-reverse) { background-color: #fff1e0; } ::host-context(.streams) { /* styles */

    }
  99. ::slotted @onishiweb

  100. ::slotted img { display: block; margin: 0; }

  101. Customising Web Components @onishiweb

  102. Custom properties @onishiweb

  103. .caption { color: var(--caption-color, white); }

  104. CSS Mixins @onishiweb

  105. .caption { --caption-styles: { color: red; font-size: 14px; }; }

    .caption { @apply(--caption-styles); }
  106. What this means for Origami @onishiweb

  107. We can start serving markup @onishiweb

  108. https://github.com/Polymer/vulcanize Bundling HTML imports

  109. https://github.com/Polymer/vulcanize HTTP/2?

  110. Using Web Components today @onishiweb

  111. The road to v1… @onishiweb

  112. http://jonrimmer.github.io/are-we-componentized-yet/

  113. Polyfill @onishiweb

  114. Libraries @onishiweb

  115. @onishiweb • Polymer • x-tag • Bosonic

  116. Beware! Here be dragons…

  117. http://webcomponents.org/

  118. https://developers.google.com/web/fundamentals/primers/customelements/

  119. Web Components are here!

  120. Almost…

  121. Honestly, like really close…

  122. 1. Automobiles 2. Trains 3. Planes

  123. 1. CSS 2. CSS Modules 3. Web Components

  124. Adam Onishi Financial Times @onishiweb Thank you!