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

Responsive Web Applications

D430439bd291dae3d8a43a413ee4ca82?s=47 snookca
October 10, 2017

Responsive Web Applications

With Container Queries!

A look at how we built a responsive web application at Shopify and what tricks we have up our sleeve to build component-based applications.

Presented at CSS Dev Conf 2017 in New Orleans.

D430439bd291dae3d8a43a413ee4ca82?s=128

snookca

October 10, 2017
Tweet

Transcript

  1. Responsive Web Applications with Container Queries

  2. Michael Rog’s Talk on Context- aware CSS #contextcss

  3. None
  4. None
  5. Beautiful Accounting Software

  6. None
  7. None
  8. None
  9. Goal #1 Evolve the design

  10. Goal #2 Support Multiple Devices

  11. None
  12. None
  13. None
  14. Goal #1 Evolve the design

  15. Goal #2 Support Multiple Devices

  16. Responsive

  17. Responsive

  18. None
  19. None
  20. Device-specific 
 design and development

  21. A team of designers and developers for each platform

  22. None
  23. Goal #1 Evolve the design

  24. Goal #2 Support Multiple Devices

  25. None
  26. None
  27. None
  28. Monolithic app with accessible templates

  29. Ignored Mobile Web

  30. Limited Mobile App

  31. None
  32. None
  33. Each horizontal block is considered in the context of the

    viewport
  34. None
  35. None
  36. None
  37. None
  38. None
  39. Each page can more easily be art directed

  40. None
  41. • No orders • One order • Less than one

    page of orders • Multiple pages of orders • Has Info Notifications • Tab overflow • Has Warning Notifications • Has limited access to features • Has different apps installed
  42. And now consider all of those things for multiple viewports

  43. And now consider all of those things for multiple languages

  44. A single page in a web application can have dozens

    of variations
  45. A component-based site has components respondingly differently to multiple contexts

  46. None
  47. None
  48. With media queries, you have to know the interplay of

    all objects in all scenarios
  49. What if…

  50. With container queries, you only have to know the interplay

    within a single object
  51. No spec for container queries

  52. None
  53. None
  54. Declare in: CSS, HTML, or 
 JavaScript

  55. https://github.com/ResponsiveImagesCG/cq-demos .element:media( min-width:500px ) {} https://github.com/tysonmatanich/elementQuery .element[min-width~="500px"] { background-color: #eee;

    }
  56. http://elementqueries.com/ @element ".element" and 
 (min-width: 500px) { .element {

    background: gold; } }
  57. https://github.com/tysonmatanich/elementQuery .element[min-width~="400px"] { }

  58. To parse CSS, either need to be on same domain

    or set up CORS
  59. https://github.com/Snugug/eq.js data-eq-pts="small: 400, medium: 600, large: 900"

  60. At HTML level, requires consistency of implementation 
 across app

  61. We chose JavaScript and built our own

  62. elements = [ { "module": ".flex--2x1", "className":"responsiveClass", "minWidth": 768, "maxWidth":

    1024 } ]
  63. Going Responsive meant a consistent feature set across all devices

  64. New features automatically have cross-device support

  65. None
  66. Went responsive in under a month† • Design considerations done

    
 in the months prior • Went component by component • Would continue to work in 
 non-responsive design • Allowed us to just flip a switch 
 when we were ready
  67. None
  68. None
  69. It’s not about the properties, it’s about the purpose.

  70. None
  71. None
  72. None
  73. Tried to use grid classes for everything

  74. .grid { } .grid--inner { } .grid--inner__first .grid--inner__last …

  75. Had to write extra classes just to define responsive story

  76. .grid { } ... .grid--responsive--a .grid--responsive--b

  77. Single purpose classes resulted in less edge cases (and less

    code!)
  78. .layout-a { display: flex; } .layout-b { display: flex; }

    .grid { display: flex; }
  79. Gzip minimizes duplicate properties really well

  80. Tables are difficult

  81. None
  82. None
  83. None
  84. None
  85. Avoid too much on the horizontal axis

  86. None
  87. None
  88. None
  89. None
  90. None
  91. Goal #1 Evolve the design

  92. Goal #2 Support Multiple Devices

  93. Goal #1 reframed: Allow anybody to make product-wide design changes

    quickly and easily
  94. Problems: • Different teams • Different deliverables • Different tech

    stacks
  95. Solutions: • Component-based approach • Design systems team to establish

    patterns • Design Systems team dedicated to 
 building and maintaining components
  96. None
  97. Make the right things easy and the wrong things hard

  98. None
  99. Yahoo! still does a custom experience per device

  100. Shopify got rid of Container Queries

  101. None
  102. <div class="two-columns"> <div class="col1"> … </div> <div class="col2"> … </div>

    </div>
  103. .two-columns { display: flex; flex-wrap: wrap; } .col1, .col2 {

    flex-grow: 1; } .col1 { flex-basis: 66%; min-width: 360px; } .col2 { flex-basis: 33%; }
  104. None
  105. None
  106. <div class="media-body"> <div class="media-content"> </div> <div class="media-actions"> <a href="…"> Button

    </a> </div> </div>
  107. .media-body { display: flex; flex-wrap: wrap; }

  108. .media-content { flex-grow: 1; flex-basis: 400px; margin-right: 20px; }

  109. .media-actions { align-self: center; margin: 20px 0; }

  110. None
  111. None
  112. <div class="box"> <div class="box-image"> <img src="…" height="150" > </div> <div

    class="box-content">...</div> </div>
  113. .box { display: flex; flex-wrap: wrap; }

  114. .box-image { flex-grow: 1; flex-shrink: 0; flex-basis: 150px; } .box-image

    > img { width: 100%; object-fit: cover; }
  115. .box-content { margin: 10px; flex-shrink: 1; flex-grow: 1; flex-basis: 60%;

    }
  116. <div class="items"> <div class="box">…</div> <div class="box">…</div> <div class="box">…</div> </div>

  117. .items { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); }

  118. None
  119. ResizeObserver

  120. Houdini

  121. What’s Houdini: • Layout API • Custom Paint API •

    Parser API • Properties and Values • Animation Workout • Typed OM • Font Metrics API
  122. None
  123. In Chrome: • Layout API • Custom Paint API •

    Parser API • Properties and Values • Animation Workout • Typed OM • Font Metrics API
  124. Layout API just gives us layout

  125. grid-template-columns: 200px 300px; grid-template-columns: 200px 300px 600w, 200px 200px 1fr

    900w;
  126. Designers should think Responsive before they need to.

  127. Container Queries enable faster development

  128. Use techniques to avoid media or container queries altogether

  129. http://ricg.io

  130. Thank you.
 http:/ /snook.ca/
 @snookca