Graduating to Grid

A presentation at An Event Apart Chicago in August 2018 in Chicago, IL, USA by Rachel Andrew

Slide 1

Slide 1

Graduating to Grid An Event Apart Chicago 2018 @rachelandrew

Slide 2

Slide 2

@rachelandrew And there was great rejoicing.

Slide 3

Slide 3

@rachelandrew https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6514853-update-css-grid

Slide 4

Slide 4

@rachelandrew https://caniuse.com/#search=grid

Slide 5

Slide 5

@rachelandrew What’s it like being in the middle of a launch of a big new CSS feature?

Slide 6

Slide 6

@rachelandrew It involved a lot of email.

Slide 7

Slide 7

@rachelandrew Grid is: • Exciting - a real game changer • Confusing - it doesn’t seem to do what I thought it would • Scary - there are so many new properties to learn!

Slide 8

Slide 8

@rachelandrew “Q. How do you feel when you see a new CSS feature announced?” –Me, in a survey question

Slide 9

Slide 9

@rachelandrew “Excited but also worried about falling behind.” –Survey response

Slide 10

Slide 10

@rachelandrew “Excited, until I share it with colleagues and they pick it apart” –Survey response

Slide 11

Slide 11

@rachelandrew “Oh no, a new way to have inconsistencies between web browsers.” –Survey response

Slide 12

Slide 12

@rachelandrew “Tired.” –Survey response

Slide 13

Slide 13

@rachelandrew I can’t tell you what to do.

Slide 14

Slide 14

@rachelandrew I can help you develop the skills to make those decisions yourself.

Slide 15

Slide 15

@rachelandrew I want you to be the amazing CSS layout person on your team.

Slide 16

Slide 16

@rachelandrew You need to understand CSS.

Slide 17

Slide 17

@rachelandrew Understanding CSS is not about learning every property and value by heart. (my main skill is “can use a search engine”)

Slide 18

Slide 18

@rachelandrew Core ideas that help CSS layout make sense.

Slide 19

Slide 19

@rachelandrew Cascading Style Sheets

Slide 20

Slide 20

@rachelandrew Inheritance - which properties will inherit values from their parent.

Slide 21

Slide 21

@rachelandrew Specificity - which rule wins when two things could apply to the same element.

Slide 22

Slide 22

@rachelandrew https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance

Slide 23

Slide 23

@rachelandrew Block and inline dimensions

Slide 24

Slide 24

@rachelandrew Horizontal Writing Mode Inline dimension or axis Block dimension or axis

Slide 25

Slide 25

@rachelandrew Vertical Writing Mode Block dimension or axis Inline dimension or axis

Slide 26

Slide 26

@rachelandrew Grid Layout in Horizontal Writing Mode Inline axis Block axis

Slide 27

Slide 27

@rachelandrew Flex Layout in Horizontal Writing Mode flex-direction: column Cross axis flex-direction: row Main axis Cross axis Main axis

Slide 28

Slide 28

@rachelandrew Sizing Matters

Slide 29

Slide 29

@rachelandrew https://codepen.io/rachelandrew/pen/ZXMwdB

Slide 30

Slide 30

@rachelandrew https://codepen.io/rachelandrew/pen/ZXMwdB row wrapper 6.20% (6.20%*4) + (2.093333%*3)

Slide 31

Slide 31

@rachelandrew https://codepen.io/rachelandrew/pen/ZXMwdB .col { margin-bottom: 1em; margin-left: 2.093333%; width: 6.20%; float: left; } .row::after { content: ""; display: block; clear: both; } .col.span2 { width: calc((6.20%*2) + 2.093333%); } .col.span3 { width: calc((6.20%*3) + (2.093333%*2)); } .col.span4 { width: calc((6.20%*4) + (2.093333%*3)); }

Slide 32

Slide 32

@rachelandrew Percentages • Ugly • Easy to understand • If they total more than 100% bad things happen. • Can be converted from an ideal pixel size using a straightforward calculation.

Slide 33

Slide 33

@rachelandrew https://codepen.io/rachelandrew/pen/eGPPaZ

Slide 34

Slide 34

@rachelandrew https://codepen.io/rachelandrew/pen/eGPPaZ Row wrapper as flex container 6.20% (6.20%*4) + (2.093333%*3)

Slide 35

Slide 35

@rachelandrew https://codepen.io/rachelandrew/pen/eGPPaZ .wrapper .row { display: flex; flex-wrap: wrap; } .col { padding: 10px; margin-bottom: 1em; margin-left: 2.093333%; width: 6.20%; flex: 0 0 auto; } .col.span2 { width: calc((6.20%*2) + 2.093333%); } .col.span3 { width: calc((6.20%*3) + (2.093333%*2)); } .col.span4 { width: calc((6.20%*4) + (2.093333%*3)); }

Slide 36

Slide 36

@rachelandrew Past layout methods create the appearance of a grid, by lining things up.

Slide 37

Slide 37

@rachelandrew CSS Intrinsic and Extrinsic Sizing https://drafts.csswg.org/css-sizing-3/

Slide 38

Slide 38

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ /* html */

<div class="box"> I am a string of text. </div> /* css */ .box { padding: 10px; border: 5px dotted rgba(255,255,255,.7); margin-bottom: 2em; }

Slide 39

Slide 39

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ available width

Slide 40

Slide 40

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ .box { width: 500px; }

Slide 41

Slide 41

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ available width 500px

Slide 42

Slide 42

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ max content min content

Slide 43

Slide 43

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ .box { width: min-content; }

Slide 44

Slide 44

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ available width min-content

Slide 45

Slide 45

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ .box { width: max-content; }

Slide 46

Slide 46

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ available width max-content

Slide 47

Slide 47

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/

<div class="fixed-width"> <div class="box"> I am a longer string of text and max-content will cause me to overflow. </div> </div>

Slide 48

Slide 48

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ .fixed-width { width: 20em; border: 5px solid rgb(255,255,255); margin-bottom: 2em; } .box { width: max-content; }

Slide 49

Slide 49

@rachelandrew https://codepen.io/rachelandrew/pen/rGqQNM/ max-content 20em

Slide 50

Slide 50

@rachelandrew https://codepen.io/rachelandrew/pen/KXGbQo/

<div class="box"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> <div>Item 4</div> </div>

Slide 51

Slide 51

@rachelandrew Items start by trying to display at max-content size. Space is reduced according to the flexbasis. In this case the size of the content. https://codepen.io/rachelandrew/pen/KXGbQo/

Slide 52

Slide 52

@rachelandrew https://codepen.io/rachelandrew/pen/KXGbQo/ flex: 1 1 auto; Items can grow and shrink so stretch to fill the container. With no extra space, items shrink as before.

Slide 53

Slide 53

@rachelandrew https://codepen.io/rachelandrew/pen/KXGbQo/ flex: 1 1 0; Items can grow and shrink so stretch to fill the container. With a flex-basis of 0 space is distributed from 0, making equal columns.

Slide 54

Slide 54

@rachelandrew https://codepen.io/rachelandrew/pen/wrYONK Flex items at min-content size Grid items at max-content size

Slide 55

Slide 55

@rachelandrew Flexbox is starting from max-content and taking space away. Grid starting at min-content and adding space.

Slide 56

Slide 56

@rachelandrew https://codepen.io/rachelandrew/pen/bomZVP/ .grid { display: grid; grid-template-columns: repeat(4, min-content); }

Slide 57

Slide 57

@rachelandrew https://codepen.io/rachelandrew/pen/bomZVP/ min-content

Slide 58

Slide 58

@rachelandrew https://codepen.io/rachelandrew/pen/bomZVP/ .grid { display: grid; grid-template-columns: repeat(4, max-content); }

Slide 59

Slide 59

@rachelandrew https://codepen.io/rachelandrew/pen/bomZVP/ max-content

Slide 60

Slide 60

@rachelandrew https://codepen.io/rachelandrew/pen/Oxqgqo .grid { display: grid; grid-template-columns: repeat(4, fit-content(15ch)); }

Slide 61

Slide 61

@rachelandrew https://codepen.io/rachelandrew/pen/Oxqgqo fit-content(15ch)

Slide 62

Slide 62

@rachelandrew https://codepen.io/rachelandrew/pen/ZXPJbQ

Slide 63

Slide 63

@rachelandrew https://codepen.io/rachelandrew/pen/ZXPJbQ grid-template-columns: repeat(12, minmax(0,1fr)); grid-column: auto / span 4;

Slide 64

Slide 64

@rachelandrew https://codepen.io/rachelandrew/pen/ZXPJbQ .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); grid-gap: 20px; } .col.span2 { grid-column: auto / span 2; } .col.span3 { grid-column: auto / span 3; } .col.span4 { grid-column: auto / span 4; }

Slide 65

Slide 65

@rachelandrew https://codepen.io/rachelandrew/pen/ZXPJbQ .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); grid-column-gap: 2.093333%; grid-row-gap: 20px; } .col.span2 { grid-column: auto / span 2; } .col.span3 { grid-column: auto / span 3; } .col.span4 { grid-column: auto / span 4; }

Slide 66

Slide 66

@rachelandrew https://slack.engineering/rebuilding-slack-com-b124c405c193 “In the end, we discovered that a column-based grid wasn’t actually needed. Since Grid allows you to create a custom grid to match whatever layout you have, we didn’t need to force it into 12 columns. Instead, we created CSS Grid objects for some of the common layout patterns in the designs.” –Rebuilding Slack.com

Slide 67

Slide 67

@rachelandrew https://codepen.io/rachelandrew/pen/RLOxMB

Slide 68

Slide 68

@rachelandrew https://codepen.io/rachelandrew/pen/RLOxMB 300px 120px

Slide 69

Slide 69

@rachelandrew https://codepen.io/rachelandrew/pen/RLOxMB .media { display: grid; grid-template-columns: fit-content(300px) 1fr; grid-gap: 20px; }

Slide 70

Slide 70

@rachelandrew https://codepen.io/rachelandrew/pen/jGRzzv/

Slide 71

Slide 71

@rachelandrew https://codepen.io/rachelandrew/pen/jGRzzv/ .panel { display: grid; grid-gap: 1px; grid-template-columns: 1fr 1fr 3fr; grid-template-rows: minmax(100px, auto) minmax(50px, auto) minmax(250px, auto) minmax(50px, auto) minmax(150px, auto); }

Slide 72

Slide 72

@rachelandrew Min 50px Max auto https://codepen.io/rachelandrew/pen/jGRzzv/

Slide 73

Slide 73

@rachelandrew Min 50px Max auto Min 50px Max auto https://codepen.io/rachelandrew/pen/jGRzzv/

Slide 74

Slide 74

@rachelandrew This is not exciting. But it will let you do exciting things.

Slide 75

Slide 75

@rachelandrew Why so complicated?

Slide 76

Slide 76

@rachelandrew More capability & flexibility means more to learn

Slide 77

Slide 77

@rachelandrew It is all just lines.

Slide 78

Slide 78

@rachelandrew https://codepen.io/rachelandrew/pen/bomPLN/

Slide 79

Slide 79

@rachelandrew https://codepen.io/rachelandrew/pen/bomPLN/ 1 1 2 3 4 5 2 3 4 5 6

Slide 80

Slide 80

@rachelandrew https://codepen.io/rachelandrew/pen/bomPLN/ .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px 100px 100px; } .item { grid-column: 2 / 5; grid-row: 2 / 4; }

Slide 81

Slide 81

@rachelandrew https://codepen.io/rachelandrew/pen/oGQXjx/ 1 1 content-start 3 content-end 5 content-start 3 4 content-end 6

Slide 82

Slide 82

@rachelandrew https://codepen.io/rachelandrew/pen/oGQXjx/ .grid { display: grid; grid-template-columns: 1fr [content-start] 1fr 1fr 1fr [content-end] 1fr; grid-template-rows: 100px [content-start] 100px 100px [content-end] 100px; } .item { grid-column: content-start / content-end; grid-row: content-start / content-end; }

Slide 83

Slide 83

@rachelandrew https://codepen.io/rachelandrew/pen/oGQXjx/ 1 1 content-start 3 content-end 5 content-start 3 4 content-end 6

Slide 84

Slide 84

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ 1 content-start 3 4 1 content-start 3 content-end 5 content content-end 6

Slide 85

Slide 85

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ .grid { display: grid; grid-template-columns: 1fr [content-start] 1fr 1fr 1fr [content-end] 1fr; grid-template-rows: 100px [content-start] 100px 100px [content-end] 100px; } .item { grid-area: content; }

Slide 86

Slide 86

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ .grid { display: grid; grid-template-columns: 1fr [content-start] 1fr 1fr 1fr [content-end] 1fr; grid-template-rows: 100px [content-start] 100px 100px [content-end] 100px; } .item { grid-area: content / content / content / content; }

Slide 87

Slide 87

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ grid-area: content / content / content / content; grid-row-start grid-column-start grid-row-end grid-column-end

Slide 88

Slide 88

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ 1 1 content-start content 3 4 content-start content 3 content-end content 5 content content-end content 6

Slide 89

Slide 89

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ grid-area: content / content / content / content; grid-row-start grid-column-start grid-row-end grid-column-end

Slide 90

Slide 90

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ grid-area: content / content / content ; grid-row-start grid-column-start grid-row-end • grid-column-end is set to the value used for grid-column-start, which is ‘content’.

Slide 91

Slide 91

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ grid-area: content / content ; grid-row-start grid-column-start • grid-row-end is set to the value used for grid-column-start, which is ‘content’. • grid-column-end is set to the value used for grid-column-start, which is ‘content’.

Slide 92

Slide 92

@rachelandrew https://codepen.io/rachelandrew/pen/QqJbyB/ grid-area: content ; grid-row-start • The other three values are set to the same as grid-row-start, so all are set to ‘content’

Slide 93

Slide 93

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG/ .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px 100px 100px; grid-template-areas: ". . . . ." ". content content content ." ". content content content ." ". . . . ." } .item { grid-area: content ; }

Slide 94

Slide 94

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG/ 1 content 3 4 content 1 content content content content content content content 3 content 5 6

Slide 95

Slide 95

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG/ 1 content 3 4 content 1 content content content content content content content 3 content 5 6

Slide 96

Slide 96

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG/ 1 1 content content-start 3 4 content content-end content content-start content content content content content content 3 content content-end 5 6

Slide 97

Slide 97

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG/ .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px 100px 100px; grid-template-areas: ". . . . ." ". content content content ." ". content content content ." ". . . . ." } .item { grid-area: content ; } .item2 { grid-row-start: content-start; grid-column-start: content-end; }

Slide 98

Slide 98

@rachelandrew https://codepen.io/rachelandrew/pen/xXQGVG

Slide 99

Slide 99

@rachelandrew You have real choice for the first time.

Slide 100

Slide 100

@rachelandrew What would be the best method to achieve this design pattern?

Slide 101

Slide 101

@rachelandrew Could we solve this problem with a new design pattern?

Slide 102

Slide 102

@rachelandrew Instead of “which patterns does our framework give us to use?”

Slide 103

Slide 103

@rachelandrew How old is the oldest CSS in your project?

Slide 104

Slide 104

@rachelandrew 368 people working on existing projects 29 had CSS in their codebase written 10 years or more ago.

Slide 105

Slide 105

@rachelandrew Old CSS in your project doesn’t mean you can’t use new CSS.

Slide 106

Slide 106

@rachelandrew This is where understanding CSS comes in really useful.

Slide 107

Slide 107

@rachelandrew https://codepen.io/rachelandrew/pen/wrbwOz/

Slide 108

Slide 108

@rachelandrew https://codepen.io/rachelandrew/pen/wrbwOz/

Slide 109

Slide 109

@rachelandrew https://codepen.io/rachelandrew/pen/wrbwOz/ img { max-width: 100%; } .gallery { display: grid; grid-template-columns: repeat(auto-fill,minmax(200px,1fr)); grid-gap: 10px 20px; grid-auto-flow: dense; } .portrait { grid-row-end: span 2; } figcaption { text-align: center; font-size: 1.5em; }

Slide 110

Slide 110

@rachelandrew Creating systems with new layout.

Slide 111

Slide 111

@rachelandrew Other layout methods still exist.

Slide 112

Slide 112

@rachelandrew https://codepen.io/rachelandrew/pen/ZXNYob/ Floating the image means the text wraps round. Defining a grid on the container means we don’t get the wrapping behaviour.

Slide 113

Slide 113

@rachelandrew https://codepen.io/rachelandrew/pen/RLmNvY/ Multi-column layout splits content into equal width columns. Using column-width of 200px means we get more columns if there is room, fewer with less available width.

Slide 114

Slide 114

@rachelandrew https://codepen.io/rachelandrew/pen/OxYVmL Flex items with the value of justify-content set to space-between. I also use flexbox to centre the word in the circle.

Slide 115

Slide 115

@rachelandrew You don’t need a grid-shaped hammer for every layout task.

Slide 116

Slide 116

@rachelandrew Off-the-shelf frameworks are designed to solve generic problems.

Slide 117

Slide 117

@rachelandrew Do you want your project to inherit the CSS issues of the rest of the world?

Slide 118

Slide 118

@rachelandrew Build your own framework* * framework doesn’t mean “all-encompassing behemoth”

Slide 119

Slide 119

@rachelandrew Solving your specific problems only will result in lighter, easier to understand code

Slide 120

Slide 120

@rachelandrew https://codepen.io/rachelandrew/pen/dVEojr/ @mixin gridded($type: grid, $col: 20em, $gap: 20px) { @if ($type == 'flex') { display: flex; flex-wrap: wrap; margin-left: -#{$gap} ; > * { flex: 1 1 $col; margin: 0 0 $gap $gap; } } @if ($type == 'grid') { display: grid; grid-template-columns: repeat(auto-fill, minmax($col,1fr)); grid-gap: $gap; } } @if ($type == 'multicol') { column-gap: $gap; column-width: $col; }

Slide 121

Slide 121

@rachelandrew https://codepen.io/rachelandrew/pen/dVEojr/ .multicol { @include gridded('multicol',200px,20px); } .grid{ @include gridded('grid',200px,20px); } .flex { @include gridded('flex',200px,20px); }

Slide 122

Slide 122

@rachelandrew https://codepen.io/rachelandrew/pen/dVEojr/

Slide 123

Slide 123

@rachelandrew Working with less capable browsers. These may not always be old browsers.

Slide 124

Slide 124

@rachelandrew A lack of understanding on one side. A lack of confidence on the other.

Slide 125

Slide 125

@rachelandrew https://web.archive.org/web/20060318055841/http://developer.yahoo.com/yui/articles/gbs/gbs_browser-chart.html

Slide 126

Slide 126

@rachelandrew Building confidence in your CSS skills will help you to make your case to use newer methods. (Although quite often asking permission is optional)

Slide 127

Slide 127

@rachelandrew Old browser versions of survey respondents cited IE11 as oldest IE supported.

Slide 128

Slide 128

@rachelandrew Old browser versions of survey respondents support IE10+

Slide 129

Slide 129

@rachelandrew https://rachelandrew.co.uk/archives/2016/11/26/should-i-try-to-use-the-ie-implementation-of-css-grid-layout/ IE10 & 11 have the -ms prefixed older version of grid layout.

Slide 130

Slide 130

@rachelandrew For other desktop browsers supporting the last 2 versions is common.

Slide 131

Slide 131

@rachelandrew https://drafts.csswg.org/css-grid-2/

Slide 132

Slide 132

@rachelandrew 1 1 2 3 4 5 2 3 4 5 6

Slide 133

Slide 133

@rachelandrew .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px 100px 100px; } .item { grid-column: 2 / 5; grid-row: 2 / 4; }

Slide 134

Slide 134

@rachelandrew .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px 100px 100px; } .item { grid-column: 2 / 5; grid-row: 2 / 4; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }

Slide 135

Slide 135

@rachelandrew 1 2 3 4 5 1 2 3 4 1 2 1 3 2 4 3 5 6

Slide 136

Slide 136

@rachelandrew .item { grid-column: 2 / 5; grid-row: 2 / 4; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; } .item > div { grid-column: 2 / 4; grid-row: 1; }

Slide 137

Slide 137

@rachelandrew http://caniuse.com/#search=css%20grid (December 2017)

Slide 138

Slide 138

@rachelandrew http://caniuse.com/#search=css%20grid (December 2017)

Slide 139

Slide 139

@rachelandrew http://gs.statcounter.com/

Slide 140

Slide 140

@rachelandrew Many browsers without support for Grid and other new CSS at this point are mobile browsers.

Slide 141

Slide 141

@rachelandrew Many of the browsers without support are most popular in areas where data is expensive or devices less powerful.

Slide 142

Slide 142

@rachelandrew “Grid too young and would need a ton of polyfills.” “Lack of a good css grid polyfill that works with postcss and supports not so old browsers” –Survey responses

Slide 143

Slide 143

@rachelandrew Stop looking for polyfills and shims. They will make the experience worse for less capable browsers and devices.

Slide 144

Slide 144

@rachelandrew “The time it takes your customer to get the information she came for.” –Jeffrey Zeldman

Slide 145

Slide 145

@rachelandrew Using Grid rather than loading a big framework can help create a better experience even for browsers that don’t support Grid.

Slide 146

Slide 146

@rachelandrew Feature Queries - use CSS to ask if the browser supports a feature before using it.

Slide 147

Slide 147

@rachelandrew https://twitter.com/dieulot/status/938858161699807233

Slide 148

Slide 148

@rachelandrew http://gs.statcounter.com/browser-version-market-share/all/india/#monthly-201703-201803

Slide 149

Slide 149

@rachelandrew Create complex layouts for browsers that support them with a few lines of CSS.

Slide 150

Slide 150

@rachelandrew Making the web available to everyone. That’s exciting.

Slide 151

Slide 151

@rachelandrew “Q. How do you feel when you see a new CSS feature announced?” –Me, in a survey question

Slide 152

Slide 152

@rachelandrew “Excited!”

Slide 153

Slide 153

Thank you! @rachelandrew