Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The Right Layout Tool for the Job

2,671 views

Published on

My talk for WebExpo Prague on CSS Layout and how we are getting to a point where we have decisions we can make over which layout method to use.

Published in: Technology
  • Be the first to comment

The Right Layout Tool for the Job

  1. 1. The Right Layout Tool for the Job. Rachel Andrew, 
 WebExpo, Prague 2016
  2. 2. Rachel Andrew rachelandrew.co.uk @rachelandrew CSS Working Group Invited Expert Google Developer Expert for Web Technologies Co-founder Perch CMS: https://grabaperch.com Contact: me@rachelandrew.co.uk
  3. 3. Modern CSS Layout? • Floats • Inline-block • display: table • Absolute & Relative positioning • Frameworks … lots of frameworks
  4. 4. Our great hopes for layout • Flexbox
 https://drafts.csswg.org/css-flexbox/ • CSS Grid Layout
 https://drafts.csswg.org/css-grid/ • Box Alignment
 https://drafts.csswg.org/css-align/
  5. 5. Getting Flexible
  6. 6. The justify- content property is set to space- between. The items at each end are placed against the container and the remaining space distributed evenly. nav ul{ display: flex; justify-content: space-between; }
  7. 7. The justify- content property is set to space- around. The items are evenly distributed in the container with a half size space at each end. nav ul{ display: flex; justify-content: space-around; }
  8. 8. The flex property • flex-grow - add space • flex-shrink - remove space • flex-basis - the initial size before any growing or shrinking
  9. 9. The initial width of our li is 300 pixels, however it can grow larger and shrink smaller than 300 pixels. .wrapper { display: flex; } .wrapper li { flex: 1 1 300px; min-width: 1px; }
  10. 10. If the value of flex-grow is 0 the boxes cannot grow. .wrapper { display: flex; } .wrapper li { flex: 0 1 300px; min-width: 1px; }
  11. 11. If the value of flex-shrink is 0 the boxes cannot shrink. .wrapper { display: flex; } .wrapper li { flex: 1 0 300px; min-width: 1px; }
  12. 12. Setting flex-grow to 2 on the 3 item. .wrapper li { flex: 1 1 300px; min-width: 1px; } .wrapper li:nth-child(3) { flex-grow: 2; }
  13. 13. With flex-basis 0 all the available space is up for grabs and can be assigned according to the flex-grow value. .wrapper li { flex: 1 1 0; min-width: 1px; } .wrapper li:nth-child(3) { flex-grow: 2; }
  14. 14. http://madebymike.com.au/demos/flexbox-tester/
  15. 15. The wonderful world of ‘auto’
  16. 16. https://drafts.csswg.org/css-flexbox/#valdef-flex-basis-auto “When specified on a flex item, the auto keyword retrieves the value of the main size property as the used flex-basis. If that value is itself auto, then the used value is content.”
  17. 17. The ‘main size’ For flex items: if flex-direction is row, main size is width if flex-direction is column, main size is height
  18. 18. flex-basis: auto If the item has a main size then it will be used for the flex-basis value. Otherwise, flex-basis is set to ‘content’.
  19. 19. The flex-basis for the items inside wrapper is auto. The items have no main size and so the defaults to content. .box { width: 600px; } .wrapper { display: flex; } .wrapper > div { flex: 1 1 auto; } flex-basis: auto
  20. 20. I don’t need to change my CSS for the flex-basis to respect the component width. .box { width: 600px; } .wrapper { display: flex; } .wrapper > div { flex: 1 1 auto; } flex-basis: auto 600px
  21. 21. I want this bar aligned to the bottom
  22. 22. Making each card a flex container means we can use flexbox for the alignment. /* the wrapper */ .inner { display: flex; } /* the cards */ .card { flex: 1 1 0; display: flex; flex-direction: column; } /* the stretching content */ .content { flex: 1 1 auto; }
  23. 23. flex: 1 1 300px; flex-grow: 1 flex-shrink: 1; flex-basis: 300px; If we allow the flex items to wrap we can see how flex-basis works by dragging the window smaller. .wrapper { display: flex; flex-flow: row wrap; } .wrapper li { flex: 1 1 300px; min-width: 1px; }
  24. 24. flex: 1 1 300px; flex-grow: 1; flex-shrink: 1; flex-basis: 300px; The 3rd item has flex: 0 1 300px; so cannot grow. .wrapper { display: flex; } .wrapper li { flex: 1 1 300px; min-width: 1px; } .wrapper li:nth-child(3) { flex: 0 1 300px; }
  25. 25. CSS Grid Layout
  26. 26. I am creating three grid column tracks, all 1fr in width. This gives me three equally sized column tracks. .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; }
  27. 27. If I create the first column as 600 pixels and then have two 1fr columns the 600 pixel track is removed from the available space and the remainder is distributed equally between the two columns. .wrapper { display: grid; grid-template-columns: 600px 1fr 1fr; }
  28. 28. With a 600 pixel column, a 1fr and a 3fr column. The 600 pixels is removed from the available space then the remaining space is divided by 4. The 1fr column gets 25% and the 3fr column 75%. .wrapper { display: grid; grid-template-columns: 600px 1fr 3fr; }
  29. 29. Flexbox for 1 dimensional layout. CSS Grid is for 2 dimensional layout.
  30. 30. repeat notation. These two track listings are the same. .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; } .wrapper { display: grid; grid-template-columns: repeat(4, 1fr); }
  31. 31. minmax() Declare a minimum and a maximum size for tracks. .wrapper { display: grid; grid-auto-rows: minmax(200px, 400px); }
  32. 32. The value of the grid-template- columns property says: repeat this track listing, auto-filing as many columns with a minimum width of 300 pixels and a maximum of 1fr. .wrapper { display: grid; grid-template-columns: 
 repeat(auto-fill, minmax(300px, 1fr)); }
  33. 33. Grid auto-placement
  34. 34. My grid auto-fills columns with a minimum width of 80px and a maximum width of 1fr. The rows will also use minmax() to by at least 80px tall. .colors { display: grid; grid-template-columns: repeat(auto-fill,minmax(80px, 1fr)); grid-gap: 2px; grid-auto-rows: minmax(80px, auto); }
  35. 35. Some items span 2 column tracks. Some span 3 column tracks. Some blocks are tall and span 4 row tracks. .span2 { grid-column-end: span 2; grid-row-end: span 2; } .span3 { grid-column-end: span 3; grid-row-end: span 3; } .tall4 { grid-row-end: span 4; }
  36. 36. The grid-auto- flow property can be set to dense. This enables a dense ‘packing mode’. .colors { display: grid; grid-template-columns: repeat(auto- fill,minmax(80px, 1fr)); grid-gap: 2px; grid-auto-rows: minmax(80px, auto); grid-auto-flow: dense; }
  37. 37. Any items with a position on the grid are placed before auto- placed items. .white { grid-column: 1 / -1; grid-row: 3; } .black { grid-column: 1 / -1; grid-row: 6; }
  38. 38. Grid Item Placement
  39. 39. I have created a grid on my wrapper element. The grid has 3 equal width columns. Rows will be created as required as we position items into them. .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; }
  40. 40. The class ‘wrapper’ is on a ul element. <ul class="wrapper"> <li class="one"> <h3>1.</h3> </li> <li class="two"> <h3>2.</h3> </li> <li class="three"> <h3>3.</h3> </li> <li class="four"> <h3>4.</h3> </li> <li class="five"> <h3>5.</h3> </li> </ul>
  41. 41. I am positioning my elements using CSS Grid Layout line-based positioning. Setting a column and a row line using the grid- column and grid- row properties. .one { grid-column: 1 / 3; grid-row: 2 / 4; } .two { grid-column: 3; grid-row: 1 / 3; } .three { grid-column: 3; grid-row: 3; } .four { grid-column: 1; grid-row: 1 / 3; } .five { grid-column: 2 / 4; grid-row: 1 ; }
  42. 42. Alignment
  43. 43. CSS Box Alignment Module Level 3 “This module contains the features of CSS relating to the alignment of boxes within their containers in the various CSS box layout models: block layout, table layout, flex layout, and grid layout.” - https://drafts.csswg.org/css-align/
  44. 44. It’s 2016. We can now centre things.
  45. 45. Box Alignment Properties - justify-content - align-content - justify-self - align-self - justify-items - align-items
  46. 46. The justify- content property is set to space- between. The items at each end are placed against the container and the remaining space distributed evenly. nav ul{ display: flex; justify-content: space-between; flex-direction: row; }
  47. 47. The justify- content property is set to space- around. The items are evenly distributed in the container with a half size space at each end. nav ul{ display: flex; justify-content: space-around; flex-direction: row; }
  48. 48. If there is space in the grid container after all column and row tracks have been added. Use space-around and space- between to space the tracks. .wrapper { width: 500px; height: 400px; display: grid; grid-gap: 10px; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(3,100px); align-content: space-around; justify-content: space-between; }
  49. 49. The value of align- items is stretch by default. If I add extra text in one navigation point the others all take the same height. nav ul{ display: flex; justify-content: space-around; flex-direction: row; align-items: stretch; }
  50. 50. If I set the value of align-items to center then we get vertical centring. nav ul{ display: flex; justify-content: space-around; flex-direction: row; align-items: center; }
  51. 51. My grid has an absolute width and height. This is larger than required for the tracks. .wrapper { width: 500px; height: 400px; display: grid; grid-gap: 10px; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(3,100px); }
  52. 52. The align-content property controls the block axis. This axis aligns the grid rows. .wrapper { width: 500px; height: 400px; display: grid; grid-gap: 10px; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(3,100px); align-content: end; }
  53. 53. The justify- content property controls the inline axis. This axis aligns the grid columns. .wrapper { width: 500px; height: 400px; display: grid; grid-gap: 10px; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(3,100px); align-content: end; justify-content: center; }
  54. 54. I can create this same layout with flexbox or Grid. With flexbox the items are laid out in a row. .wrapper { display: flex; } .wrapper li { flex: 1 0 25%; }
  55. 55. The first item is at the default stretch and as the tallest item is dictating the height of the flex container. The second is entered in the container. The third aligned to the start. The fourth aligned to the end. .wrapper li:nth-child(2) { align-self: center; } .wrapper li:nth-child(3) { align-self: flex-start; } .wrapper li:nth-child(4) { align-self: flex-end; }
  56. 56. For Grid I use a single row, 4 column Grid. .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; }
  57. 57. Grid alignment properties for the three landscape images. .wrapper li:nth-child(2) { align-self: center; } .wrapper li:nth-child(3) { align-self: start; } .wrapper li:nth-child(4) { align-self: end; }
  58. 58. Putting it together: a form
  59. 59. 100vh body { align-content: center; justify-content: center; }
  60. 60. Aligning the grid. body { height: 100vh; display: grid; grid-template-columns: 80%; align-content: center; justify-content: center; }
  61. 61. .account { align-self: end; }
  62. 62. 1fr 1fr 1fr 1fr 1fr 2fr 2fr .login > div .login > div .login > div.actions
  63. 63. Setting align- items to centre lines the fields and labels up on their centre line. .login > div { display: grid; grid-template-columns: 1fr 2fr; align-items: center; } .login > div.actions { grid-template-columns: 1fr 1fr 1fr; }
  64. 64. Hero Panels
  65. 65. Using the minmax() function with grid-auto-rows. .home-hero { display: grid; grid-gap: 1px; grid-auto-rows: minmax(150px, auto); }
  66. 66. An item on the grid can become a grid or flex container itself. In this case I am using flexbox and auto margins to push my content to the bottom of the box. .special { display: flex; flex-direction: column; } .special h3{ margin-top: auto; }
  67. 67. But, what about old browsers?!
  68. 68. http://caniuse.com/#feat=css-grid
  69. 69. http://caniuse.com/#feat=css-grid
  70. 70. http://gridbyexample.com/browsers
  71. 71. Say hello to Feature Queries.
  72. 72. I have set three classes to display: none; .has-flex, .has-grid, .has-grid-shapes { display: none; }
  73. 73. My @supports rule tests for support of the display property with a value of flex. If it is supported we show the div. @supports (display: flex) { .has-flex { display: block; } }
  74. 74. My @supports rule tests for support of the display property with a value of grid. If it is supported we show the div. @supports (display: grid) { .has-grid { display: block; } }
  75. 75. My @supports rule tests for support of the display property with a value of grid AND shape- outside:circle. If it is supported we show the div. @supports (display: grid) and (shape-outside:circle()) { .has-grid-shapes { display: block; } }
  76. 76. http://caniuse.com/#feat=css-featurequeries
  77. 77. Defaults for all browsers will be loaded by even really old browsers. body { padding-top: 20%; } h1, .login, .account, .contact{ width:80%; margin: 0 auto; }
  78. 78. Within a Feature Query we add some information for flexbox supporting browsers. @supports (display: flex) { body { padding:0; height: 100vh; display: flex; align-items: center; justify-content: center; flex-direction: column; } h1, .login, .account, .contact { margin: 0; width: 80%; } }
  79. 79. The Feature Query for Grid supporting browsers. @supports (display: grid) { body { display: grid; grid-template-columns: 80%; align-content: center; align-items: stretch; } @media (min-width: 650px) { body { grid-template-columns: repeat(2, minmax(150px, 30%)); } h1, .login { grid-column-end: span 2; width: auto; } .login > div { display: grid; grid-template-columns: 1fr 2fr; align-items: center; } .login > div.actions { grid-template-columns: 1fr 1fr 1fr; } .account { border-right: 1px dotted rgb(191, 216, 227); padding: 0 10px 0 0; align-self: end; width: auto; } .contact { padding: 0 0 0 10px; width: auto; } } }
  80. 80. Your users ‘grow into’ enhancements as their browsers auto-update.
  81. 81. Accessibility
  82. 82. Power and responsibility • Good = creating the most accessible source order and using Grid or Flexbox to get the optimal display for each device. • Bad = using Grid or Flexbox as an excuse to forget about the source. • Terrible - stripping out semantic elements to make everything a grid or flex item.
  83. 83. Léonie Watson | On CSS accessibility and drinking tea | CSS Day 2016 https://vimeo.com/180566024 Also see: 
 http://tink.uk/flexbox-the-keyboard-navigation-disconnect/
  84. 84. https://drafts.csswg.org/css-grid/#order-accessibility “Authors must use order and the grid- placement properties only for visual, not logical, reordering of content. Style sheets that use these features to perform logical reordering are non- conforming.”
  85. 85. Performance
  86. 86. https://jakearchibald.com/2014/dont-use-flexbox-for-page-layout/
  87. 87. https://blogs.igalia.com/jfernandez/2015/06/24/performance-on-grid-layout/
  88. 88. Why are we looking at something I can’t use yet?
  89. 89. https://wiki.csswg.org/ideas/mistakes
  90. 90. Get involved with developing specs! • While a spec is being developed your feedback is wanted and can be included in the spec. • Wait until browsers ship and you lose that chance. • It just got easier. CSS Spec issues are now on GitHub.
 http://logs.csswg.org/irc.w3.org/css/2016-05-10/#e684439
  91. 91. Do a good deed for your future self.
  92. 92. Thank you Slides & Resources: https://cssgrid.me/WebExpo16 http://csslayout.news - sign up for my weekly CSS Layout email — @rachelandrew | me@rachelandrew.co.uk — https://rachelandrew.co.uk | https://grabaperch.com

×