Building Intelligent Layouts with CSS Grid

A presentation at Upfront Conf in March 2019 in Manchester, UK by Michelle Barker

Slide 1

Slide 1

Building Intelligent Layouts with CSS Grid @mbarker_84

Slide 2

Slide 2

“Intrinsic Web Design” Jen Simmons @mbarker_84

Slide 3

Slide 3

@mbarker_84

Slide 4

Slide 4

@mbarker_84

Slide 5

Slide 5

css-irl.info

Slide 6

Slide 6

Why do we need Grid? 2D layout @mbarker_84

Slide 7

Slide 7

“Flexbox is great for taking a bunch of oddly-sized things and returning the most reasonable layout for those things” Rachel Andrew @mbarker_84

Slide 8

Slide 8

Why do we need Grid? Simpler HTML and CSS @mbarker_84

Slide 9

Slide 9

Why do we need Grid? Complete control @mbarker_84

Slide 10

Slide 10

Grid terminology @mbarker_84

Slide 11

Slide 11

Grid terminology Grid display: grid; @mbarker_84

Slide 12

Slide 12

Grid terminology Tracks grid-template-rows @mbarker_84

Slide 13

Slide 13

Grid terminology Tracks grid-template-columns @mbarker_84

Slide 14

Slide 14

Grid terminology Cells @mbarker_84

Slide 15

Slide 15

Grid terminology Grid areas @mbarker_84

Slide 16

Slide 16

Grid terminology Gutters column-gap (Formerly grid-column-gap) @mbarker_84

Slide 17

Slide 17

Grid terminology Gutters row-gap (Formerly grid-row-gap) @mbarker_84

Slide 18

Slide 18

Defining a grid @mbarker_84

Slide 19

Slide 19

CSS .grid { display: grid; } @mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 20

Slide 20

CSS .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; } @mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 21

Slide 21

CSS .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; column-gap: 20px; row-gap: 20px; } @mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 22

Slide 22

@mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 23

Slide 23

CSS repeat() .grid { display: grid; grid-template-columns: repeat(4, 200px); grid-template-rows: repeat(4, 150px); } @mbarker_84 grid-gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 24

Slide 24

CSS Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); } @mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 25

Slide 25

CSS Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); gap: 20px; // row-gap / column-gap } @mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 26

Slide 26

CSS Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } @mbarker_84 grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 27

Slide 27

Fr a fraction of the leftover space in the grid container @mbarker_84

Slide 28

Slide 28

CSS Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } @mbarker_84 grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 29

Slide 29

1fr @mbarker_84 1fr 1fr 2fr

Slide 30

Slide 30

CSS Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(3, 200px) 1fr; } @mbarker_84 grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 31

Slide 31

200px @mbarker_84 200px 200px 1fr codepen.io/michellebarker/pen/wEdjqX

Slide 32

Slide 32

Implicit vs Explicit tracks @mbarker_84

Slide 33

Slide 33

CSS Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; } @mbarker_84 gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 34

Slide 34

CSS Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 150px); grid-auto-rows: 150px; } @mbarker_84 gap: 20px; codepen.io/michellebarker/pen/eLZwVg

Slide 35

Slide 35

@mbarker_84 codepen.io/michellebarker/pen/eLZwVg

Slide 36

Slide 36

Placing items @mbarker_84

Slide 37

Slide 37

HTML Auto-placement <div class=”grid”> <div class=”grid__item”>1</div> <div class=”grid__item”>2</div> <div class=”grid__item”>3</div> </div> @mbarker_84 codepen.io/michellebarker/pen/gdrVXP

Slide 38

Slide 38

@mbarker_84 codepen.io/michellebarker/pen/gdrVXP

Slide 39

Slide 39

<header> <main> <aside> codepen.io/michellebarker/pen/YOqmjP

Slide 40

Slide 40

HTML Placing items by grid line <div class=”grid”> <header></header> <main></main> <aside></aside> </div> @mbarker_84

Slide 41

Slide 41

@mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 42

Slide 42

CSS Placing items by grid line header { grid-column-start: 1; grid-column-end: 5; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 43

Slide 43

@mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 44

Slide 44

CSS Placing items by grid line main { grid-column-start: 1; grid-column-end: 4; grid-row-start: 2; grid-row-end: 5; } aside { grid-column-start: 4; grid-column-end: 5; grid-row-start: 2; grid-row-end: 4; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 45

Slide 45

@mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 46

Slide 46

CSS header { grid-column: 1 / 5; } main { grid-column: 1 / 4; grid-row: 2 / 5; } aside { // grid-column: 4 / 5; - unnecessary as will be auto-placed grid-row: span 2; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 47

Slide 47

@mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 48

Slide 48

CSS Start line / end line main { grid-column: 1 / 4; grid-row: 2 / 4; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 49

Slide 49

CSS Span (with auto-placement) main { grid-column: span 3; grid-row: 2 / 4; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 50

Slide 50

CSS Start line / span main { grid-column: 1 / span 3; grid-row: 2 / 4; } @mbarker_84 codepen.io/michellebarker/pen/YOQLLZ

Slide 51

Slide 51

main { grid-column: 4 / span 3; } @mbarker_84 codepen.io/michellebarker/pen/rRoLRe

Slide 52

Slide 52

CSS Span / end line main { grid-column: span 3 / 4; grid-row: 2 / 4; } @mbarker_84 codepen.io/michellebarker/pen/YOqmjP

Slide 53

Slide 53

CSS Naming grid lines .grid { display: grid; grid-template-columns: [header-start main-start] repeat(3, 1fr) [main-end] 1fr [header-end]; grid-auto-rows: 150px; } @mbarker_84 codepen.io/michellebarker/pen/OobJaa

Slide 54

Slide 54

header-start main-start @mbarker_84 main-end header-end codepen.io/michellebarker/pen/OobJaa

Slide 55

Slide 55

CSS header { grid-column: header; } main { grid-column: main; grid-row: span 3; } @mbarker_84 codepen.io/michellebarker/pen/rqZevv

Slide 56

Slide 56

CSS grid-template-areas .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; grid-template-areas: gap: 20px; } @mbarker_84 “h “m “m “m h m m m h m m m h” a” a” .”;

Slide 57

Slide 57

CSS grid-template-areas header { grid-area: h; } main { grid-area: m; } aside { grid-area: a; } @mbarker_84

Slide 58

Slide 58

CSS Grid for Complex Components A Case Study @mbarker_84

Slide 59

Slide 59

Slide 60

Slide 60

Slide 61

Slide 61

@mbarker_84

Slide 62

Slide 62

@mbarker_84

Slide 63

Slide 63

HTML

<div class=”grid”> <h2 class=”grid__heading”></h2> <figure class=”grid__image”></figure> <div class=”grid__body”></div> </div>

Slide 64

Slide 64

Some rules @mbarker_84

Slide 65

Slide 65

Dynamic content @mbarker_84

Slide 66

Slide 66

The heading must always be vertically centred over the image @mbarker_84

Slide 67

Slide 67

The heading must always be vertically centred over the image …no matter the size of the image or the text @mbarker_84

Slide 68

Slide 68

Text block must align to the top of the image @mbarker_84

Slide 69

Slide 69

Text block must align to the top of the image …unless the text is too long @mbarker_84

Slide 70

Slide 70

Space must always be maintained between the text block and heading @mbarker_84

Slide 71

Slide 71

Context-aware @mbarker_84

Slide 72

Slide 72

CSS Grid 2D Layout @mbarker_84

Slide 73

Slide 73

@mbarker_84

Slide 74

Slide 74

@mbarker_84

Slide 75

Slide 75

@mbarker_84

Slide 76

Slide 76

@mbarker_84

Slide 77

Slide 77

grid-template-columns: repeat(26, 1fr); @mbarker_84

Slide 78

Slide 78

grid-template-columns: repeat(26, 1fr); @mbarker_84

Slide 79

Slide 79

1fr @mbarker_84 repeat(24, 60px) 1fr

Slide 80

Slide 80

grid-template-columns: 1fr repeat(24, 60px) 1fr; @mbarker_84

Slide 81

Slide 81

minmax() minmax(20px, 1fr) Minimum size @mbarker_84 Maximum size

Slide 82

Slide 82

minmax(20px, 1fr) minmax(0, 60px) @mbarker_84 codepen.io/michellebarker/pen/wYGMPQ

Slide 83

Slide 83

grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @mbarker_84

Slide 84

Slide 84

grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @mbarker_84

Slide 85

Slide 85

grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @mbarker_84

Slide 86

Slide 86

CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) // flexible outer column repeat(24, minmax(0, 60px)) // 24 central columns minmax(20px, 1fr); // flexible outer column column-gap: 20px; }

Slide 87

Slide 87

grid-template-rows: 1fr auto 1fr; @mbarker_84

Slide 88

Slide 88

CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); grid-template-rows: 1fr auto 1fr; } @mbarker_84 column-gap: 20px;

Slide 89

Slide 89

CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); grid-template-rows: 1fr auto 1fr; gap: 40px 20px; } @mbarker_84

Slide 90

Slide 90

CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); grid-template-rows: 1fr auto 1fr; gap: 40px 20px; align-items: center; } @mbarker_84

Slide 91

Slide 91

CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @mbarker_84

Slide 92

Slide 92

CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @mbarker_84

Slide 93

Slide 93

CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @mbarker_84

Slide 94

Slide 94

CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; grid-row: heading; } @mbarker_84

Slide 95

Slide 95

CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; } @mbarker_84 grid-row: heading;

Slide 96

Slide 96

CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; grid-row: heading; } @mbarker_84

Slide 97

Slide 97

@mbarker_84

Slide 98

Slide 98

@mbarker_84

Slide 99

Slide 99

I didn’t solve this problem @mbarker_84

Slide 100

Slide 100

Gutter rows @mbarker_84

Slide 101

Slide 101

Secret hidden row @mbarker_84

Slide 102

Slide 102

grid-template-rows: 1fr auto 40px auto 40px auto; @mbarker_84

Slide 103

Slide 103

grid-template-rows: 1fr auto 40px auto 40px auto; @mbarker_84

Slide 104

Slide 104

grid-template-rows: 1fr auto 40px auto 40px auto; @mbarker_84

Slide 105

Slide 105

grid-template-rows: 1fr auto 40px auto 40px auto; @mbarker_84

Slide 106

Slide 106

@mbarker_84

Slide 107

Slide 107

@mbarker_84

Slide 108

Slide 108

CSS .grid { … grid-template-rows: [text-start] 1fr auto [text-end] 40px // gap [heading-start] auto [heading-start] 40px // gap auto; … } @mbarker_84

Slide 109

Slide 109

.grid__body { grid-row: text; } @mbarker_84

Slide 110

Slide 110

@mbarker_84

Slide 111

Slide 111

grid-template-rows: auto 40px auto 40px auto 1fr; Secret hidden row @mbarker_84

Slide 112

Slide 112

CSS .grid—text-bottom { grid-template-rows: auto 40px [heading-start] auto [heading-end] 40px [text-start] auto 1fr [text-end]; // hidden row } @mbarker_84

Slide 113

Slide 113

CSS .grid—text-bottom .grid__body { align-self: flex-end; } @mbarker_84

Slide 114

Slide 114

CSS .grid—text-bottom { grid-template-rows: [media-start] auto 40px [heading-start] auto [heading-end] 40px [text-start] auto [media-end] 1fr [text-end]; } Component variants .grid—text-bottom .grid__body { align-self: flex-end; } @mbarker_84

Slide 115

Slide 115

SCSS /* Second variant of our component */ .grid—2 { .grid__image { grid-column: 13 / outer-end; } .grid__body { grid-column: wrapper-start / span 5; } } @mbarker_84

Slide 116

Slide 116

CSS Variables (a.k.a. Custom Properties) @mbarker_84

Slide 117

Slide 117

CSS Variables @mbarker_84

Dynamic variables

Slide 118

Slide 118

CSS Defining variables :root { —bgColor: red; } @mbarker_84

Slide 119

Slide 119

CSS Using variables .my-component { background-color: var(—bgColor); } @mbarker_84

Slide 120

Slide 120

CSS .grid__image { grid-column: var(—mediaColStart) / var(—mediaColEnd); grid-row: media; } .grid__body { grid-column: var(—textColStart) / span 5; grid-row: text; } @mbarker_84

Slide 121

Slide 121

CSS .grid__image { grid-column: var(—mediaColStart) / var(—mediaColEnd); } grid-row: media; .grid__body { grid-column: var(—textColStart) / span 5; grid-row: text; } @mbarker_84

Slide 122

Slide 122

CSS .grid__image { grid-column: var(—mediaColStart) / var(—mediaColEnd); grid-row: media; } .grid__body { grid-column: var(—textColStart) / span 5; } @mbarker_84 grid-row: text;

Slide 123

Slide 123

CSS .grid { —mediaColStart: wrapper-start; —mediaColEnd: 14; —textColStart: -8; } .grid—-2 { —mediaColStart: 13; —mediaColEnd: outer-end; —textColStart: 3; } @mbarker_84

Slide 124

Slide 124

codepen.io/michellebarker/pen/yGzWme @mbarker_84

Slide 125

Slide 125

Resources Grid by Example (Rachel Andrew) gridbyexample.com Layout Land (Jen Simmons) layout.land CSS Grid Playground (MDN) mozilladevelopers.github.io/playground/css-grid CSS { In Real Life } css-irl.info

Slide 126

Slide 126

Thank you for listening @mbarker_84 / @CSSInRealLife @mbarker_84