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

Responsive Web Applications

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.

snookca

October 10, 2017
Tweet

More Decks by snookca

Other Decks in Technology

Transcript

  1. Responsive Web
    Applications
    with Container Queries

    View Slide

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

    View Slide

  3. View Slide

  4. View Slide

  5. Beautiful
    Accounting
    Software

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. Goal #1
    Evolve the design

    View Slide

  10. Goal #2
    Support Multiple
    Devices

    View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. Goal #1
    Evolve the design

    View Slide

  15. Goal #2
    Support Multiple
    Devices

    View Slide

  16. Responsive

    View Slide

  17. Responsive

    View Slide

  18. View Slide

  19. View Slide

  20. Device-specific 

    design and
    development

    View Slide

  21. A team of designers
    and developers for
    each platform

    View Slide

  22. View Slide

  23. Goal #1
    Evolve the design

    View Slide

  24. Goal #2
    Support Multiple
    Devices

    View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. Monolithic app with
    accessible templates

    View Slide

  29. Ignored Mobile Web

    View Slide

  30. Limited Mobile App

    View Slide

  31. View Slide

  32. View Slide

  33. Each horizontal block
    is considered in the
    context of the viewport

    View Slide

  34. View Slide

  35. View Slide

  36. View Slide

  37. View Slide

  38. View Slide

  39. Each page can more
    easily be art directed

    View Slide

  40. View Slide

  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

    View Slide

  42. And now consider all of
    those things for
    multiple viewports

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  46. View Slide

  47. View Slide

  48. With media queries,
    you have to know the
    interplay of all objects
    in all scenarios

    View Slide

  49. What if…

    View Slide

  50. With container
    queries, you only have
    to know the interplay
    within a single object

    View Slide

  51. No spec for
    container queries

    View Slide

  52. View Slide

  53. View Slide

  54. Declare in:
    CSS,
    HTML, or 

    JavaScript

    View Slide

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

    View Slide

  56. http://elementqueries.com/
    @element ".element" and 

    (min-width: 500px) {
    .element {
    background: gold;
    }
    }

    View Slide

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

    View Slide

  58. To parse CSS, either
    need to be on same
    domain or set up CORS

    View Slide

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

    View Slide

  60. At HTML level, requires
    consistency of
    implementation 

    across app

    View Slide

  61. We chose JavaScript
    and built our own

    View Slide

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

    View Slide

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

    View Slide

  64. New features
    automatically have
    cross-device support

    View Slide

  65. View Slide

  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

    View Slide

  67. View Slide

  68. View Slide

  69. It’s not about the
    properties, it’s about
    the purpose.

    View Slide

  70. View Slide

  71. View Slide

  72. View Slide

  73. Tried to use grid
    classes for
    everything

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. .layout-a { display: flex; }
    .layout-b { display: flex; }
    .grid { display: flex; }

    View Slide

  79. Gzip minimizes
    duplicate properties
    really well

    View Slide

  80. Tables are difficult

    View Slide

  81. View Slide

  82. View Slide

  83. View Slide

  84. View Slide

  85. Avoid too much on
    the horizontal axis

    View Slide

  86. View Slide

  87. View Slide

  88. View Slide

  89. View Slide

  90. View Slide

  91. Goal #1
    Evolve the design

    View Slide

  92. Goal #2
    Support Multiple
    Devices

    View Slide

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

    View Slide

  94. Problems:
    • Different teams
    • Different deliverables
    • Different tech stacks

    View Slide

  95. Solutions:
    • Component-based approach
    • Design systems team to establish patterns
    • Design Systems team dedicated to 

    building and maintaining components

    View Slide

  96. View Slide

  97. Make the right
    things easy and the
    wrong things hard

    View Slide

  98. View Slide

  99. Yahoo! still does a
    custom experience
    per device

    View Slide

  100. Shopify got rid of
    Container Queries

    View Slide

  101. View Slide





  102. View Slide

  103. .two-columns {
    display: flex;
    flex-wrap: wrap;
    }
    .col1, .col2 { flex-grow: 1; }
    .col1 {
    flex-basis: 66%;
    min-width: 360px;
    }
    .col2 {
    flex-basis: 33%;
    }

    View Slide

  104. View Slide

  105. View Slide





  106. Button


    View Slide

  107. .media-body {
    display: flex;
    flex-wrap: wrap;
    }

    View Slide

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

    View Slide

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

    View Slide

  110. View Slide

  111. View Slide





  112. ...

    View Slide

  113. .box {
    display: flex;
    flex-wrap: wrap;
    }

    View Slide

  114. .box-image {
    flex-grow: 1;
    flex-shrink: 0;
    flex-basis: 150px;
    }
    .box-image > img {
    width: 100%;
    object-fit: cover;
    }

    View Slide

  115. .box-content {
    margin: 10px;
    flex-shrink: 1;
    flex-grow: 1;
    flex-basis: 60%;
    }

    View Slide






  116. View Slide

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

    View Slide

  118. View Slide

  119. ResizeObserver

    View Slide

  120. Houdini

    View Slide

  121. What’s Houdini:
    • Layout API
    • Custom Paint API
    • Parser API
    • Properties and Values
    • Animation Workout
    • Typed OM
    • Font Metrics API

    View Slide

  122. View Slide

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

    View Slide

  124. Layout API just gives
    us layout

    View Slide

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

    View Slide

  126. Designers should
    think Responsive
    before they need to.

    View Slide

  127. Container Queries
    enable faster
    development

    View Slide

  128. Use techniques to
    avoid media or
    container queries
    altogether

    View Slide

  129. http://ricg.io

    View Slide

  130. Thank you.

    http:/
    /snook.ca/

    @snookca

    View Slide