Graduating to Grid

A presentation at An Event Apart Denver: Special Edition 2017 in December 2017 in Denver, CO, USA by Rachel Andrew

Slide 1

Slide 1

Graduating to Grid An Event Apart Denver 2017 @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 / Row axis Block / Column 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

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

Slide 31

Slide 31

https://codepen.io/rachelandrew/pen/ZXMwdB @rachelandrew .col { margin-bottom: 1em; margin-left: 2.093333%; width: 6.20%; float: left; } .row::after { content: ""; display: block; clear: both; } ! s e g a t n e c r e P ! g n i r a Cle ! h t a m n u F .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

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

Slide 35

Slide 35

https://codepen.io/rachelandrew/pen/eGPPaZ @rachelandrew .wrapper .row { display: flex; flex-wrap: wrap; } .col { ! s e g padding: 10px; a t n e c r margin-bottom: 1em; Pe margin-left: 2.093333%; ! s m e t i width: 6.20%; x e fl e l b i flex: 0 0 auto; x e fl n I } ! h t a m n u F .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

https://codepen.io/rachelandrew/pen/rGqQNM/ @rachelandrew /* 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

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

Slide 40

Slide 40

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

Slide 41

Slide 41

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

Slide 42

Slide 42

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

Slide 43

Slide 43

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

Slide 44

Slide 44

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

Slide 45

Slide 45

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

Slide 46

Slide 46

https://codepen.io/rachelandrew/pen/rGqQNM/ @rachelandrew 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

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

Slide 49

Slide 49

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

Slide 50

Slide 50

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

<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

https://codepen.io/rachelandrew/pen/KXGbQo/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/KXGbQo/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/wrYONK @rachelandrew 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

https://codepen.io/rachelandrew/pen/bomZVP/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/bomZVP/ @rachelandrew 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

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

Slide 62

Slide 62

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

Slide 63

Slide 63

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

Slide 64

Slide 64

https://codepen.io/rachelandrew/pen/ZXPJbQ @rachelandrew .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

https://slack.engineering/rebuilding-slack-com-b124c405c193 @rachelandrew “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

https://codepen.io/rachelandrew/pen/RLOxMB @rachelandrew 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

https://codepen.io/rachelandrew/pen/jGRzzv/ @rachelandrew .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

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

Slide 80

Slide 80

https://codepen.io/rachelandrew/pen/bomPLN/ @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 81

Slide 81

https://codepen.io/rachelandrew/pen/oGQXjx/ @rachelandrew 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

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

Slide 84

Slide 84

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

Slide 85

Slide 85

https://codepen.io/rachelandrew/pen/QqJbyB/ @rachelandrew .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

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

Slide 88

Slide 88

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

Slide 89

Slide 89

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

Slide 90

Slide 90

https://codepen.io/rachelandrew/pen/QqJbyB/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/QqJbyB/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/QqJbyB/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/xXQGVG/ @rachelandrew .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

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

Slide 95

Slide 95

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

Slide 96

Slide 96

https://codepen.io/rachelandrew/pen/xXQGVG/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/wrbwOz/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/RLmNvY/ @rachelandrew 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

https://codepen.io/rachelandrew/pen/OxYVmL @rachelandrew 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

https://codepen.io/rachelandrew/pen/dVEojr/ @rachelandrew @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 39% of survey respondents cited IE11 as oldest IE supported.

Slide 128

Slide 128

@rachelandrew Old browser versions 63% 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 http://caniuse.com/#search=css%20grid

Slide 132

Slide 132

@rachelandrew http://caniuse.com/#search=css%20grid

Slide 133

Slide 133

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

Slide 134

Slide 134

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

Slide 135

Slide 135

@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 136

Slide 136

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

Slide 137

Slide 137

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

Slide 138

Slide 138

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

Slide 139

Slide 139

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

Slide 140

Slide 140

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

Slide 141

Slide 141

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

Slide 142

Slide 142

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

Slide 143

Slide 143

@rachelandrew “Excited!”

Slide 144

Slide 144

Thank you! @rachelandrew