The Grid - The Future of CSS Layout

A presentation at Front-end Day at Making Waves in April 2016 in Oslo, Norway by Ronny Siikaluoma

Slide 1

Slide 1

THE GRID The future of CSS layout

Slide 2

Slide 2

Evolution of web layout

Slide 3

Slide 3

<table>

Slide 4

Slide 4

float

Slide 5

Slide 5

display: inline-block

Slide 6

Slide 6

display: table

Slide 7

Slide 7

position: absolute

Slide 8

Slide 8

CSS Frameworks

Slide 9

Slide 9

display: flex

Slide 10

Slide 10

Cost of taming layout • Hours spent learning non-obvious concepts • Sacrifice semantics in order to do responsive layout • Rely on frameworks to work out the numbers • Extra markup to create grids • Abstract layout hack with preprocessors (mixins etc.)

Slide 11

Slide 11

display: grid

Slide 12

Slide 12

CSS Grid layout A system designed for handling «2 dimentional» layout

Slide 13

Slide 13

Browser support

Slide 14

Slide 14

In-development. Unprefixed support with flag enabled In-development. Some features supported unprefixed in nightlies -webkit prefix supported in Webkit Nightlies IE10 support old syntax with –ms prefix Is on Edge backlog, marked as High Priority

Slide 15

Slide 15

The basics

Slide 16

Slide 16

Basic HTML structure

<div class=”grid grid—1”> <div class=”grid__item grid__item—1”>1</div> <div class=”grid__item grid__item—2”>2</div> </div>

Slide 17

Slide 17

Establish grid context to parent using display: grid .grid { display: grid; }

Slide 18

Slide 18

Describe grid using properties: grid-template-columns grid-template-rows .grid—1 { grid-template-columns: 100px 100px 100px; grid-template-rows: auto auto; }

Slide 19

Slide 19

Position items (children) using: grid-column-start grid-column-end .grid__item—1 { grid-column-start: 1; grid-column-end: 2; grid-row-start: 1; grid-row-end: 2; } grid-row-start grid-row-end A

Slide 20

Slide 20

Position item bottom center .grid__item—2 { grid-column-start: 2; grid-column-end: 3; grid-row-start: 2; grid-row-end: 3; } B

Slide 21

Slide 21

Span an item over more tracks by changing column-end/ row-end .grid__item—2 { grid-column-start: 2; grid-column-end: 4; grid-row-start: 2; grid-row-end: 3; } B

Slide 22

Slide 22

Long hand Short hand .grid__item—1 { grid-column-start: 1; grid-column-end: 2; grid-row-start: 1; grid-row-end: 2; } .grid__item—1 { grid-column: 1 / 2; grid-row: 1 / 2; } .grid__item—2 { grid-column-start: 2; grid-column-end: 4; grid-row-start: 2; grid-row-end: 3; } .grid__item—2 { grid-column: 2 / 4; grid-row: 2 / 3; }

Slide 23

Slide 23

Even shorter: grid-area .grid__item—1 { grid-area: 1 / 1 / 2 / 2; } .grid__item—2 { grid-area: 2 / 2 / 3 / 4; } A B

Slide 24

Slide 24

Terminology

Slide 25

Slide 25

Grid CONTAINER • The element on which display: grid is applied. • It’s the direct parent of all the grid items.

Slide 26

Slide 26

Grid ITEM • The children (e.g. direct descendants) of the grid container.

Slide 27

Slide 27

Grid LINES • Line either horizontal or vertical • Referred to by number • Can be named Column Line 2

Slide 28

Slide 28

Grid CELL • Smallest unit in a grid • The space between four grid lines • «table-cell» Cell between: - Row Line 2 and 3, - Column Line 2 and 3

Slide 29

Slide 29

Grid TRACK • The space between two Grid Lines • Tracks can be horizontal or vertical (rows or columns) Track between: - Row Line 2 and 3

Slide 30

Slide 30

Grid AREA • Any area of the Grid bound by 4 Grid Lines • Can contain many Grid Cells Area between: - Row Line 1 and 3, - Column Line 1 and 3

Slide 31

Slide 31

Movin’ on

Slide 32

Slide 32

The fr unit • A fraction is a part of the available space in a Track • Essentially a part of whats left after space is subtracted • Acts similar as flex-grow in Flexbox

Slide 33

Slide 33

Creating three column tracks. Using 1fr in width We get three equally sized columns

<!— HTML —> <div class=”grid grid—2”> <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item </div>

grid__item—1”></div> grid__item—2”></div> grid__item—3”></div> grid__item—4”></div> grid__item—5”></div> grid__item—6”></div> // SCSS .grid—2 { grid-template-columns: 1fr 1fr 1fr; } 1fr 1fr 1fr

Slide 34

Slide 34

First column = 600px 2 x 1fr columns After 600px is subtracted, the rest is equally devided between the two fr-columns

<!— HTML —> <div class=”grid grid—2”> <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item </div>

grid__item—1”></div> grid__item—2”></div> grid__item—3”></div> grid__item—4”></div> grid__item—5”></div> grid__item—6”></div> // SCSS .grid—2 { grid-template-columns: 600px 1fr 1fr; } 600px 1fr 1fr

Slide 35

Slide 35

First column = 600px 1 x 1fr column 1 x 3fr column After 600px is subtracted, the rest is devided by 4

<!— HTML —> <div class=”grid grid—2”> <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item <div class=”grid__item </div>

grid__item—1”></div> grid__item—2”></div> grid__item—3”></div> grid__item—4”></div> grid__item—5”></div> grid__item—6”></div> 1fr = 25% 3fr = 75% // SCSS .grid—2 { grid-template-columns: 600px 1fr 3fr; } 600px 1fr 3fr

Slide 36

Slide 36

«Holy Grail» using CSS Grid grid-gap = shorthand for

<!— HTML —> <div class=”grid grid—grail”> <header class=”grid__item header”>Header</header> <article class=”grid__item content”>Content</article> <div class=”grid__item sidebar1”>Sidebar 1</div> <div class=”grid__item sidebar2”>Sidebar 2</div> <footer class=”grid__item footer”>Footer</footer> </div> // SCSS .grid—grail { grid-template-columns: 300px 1fr 300px; grid-template-rows: auto; grid-column-gap: 20px;

grid-column-gap + grid-row-gap } .header .content .sidebar1 .sidebar2 .footer { { { { { grid-column: grid-column: grid-column: grid-column: grid-column: 1 2 1 3 1 / / / / / 4; 3; 2; 4; 4; } grid-row: grid-row: grid-row: grid-row: 2 2 2 3 / / / / 3; 3; 3; 4; } } } }

Slide 37

Slide 37

Holy Grail Header 300px 1fr (fluid) 300px Footer // SCSS .grid—grail { grid-template-columns: 300px 1fr 300px; grid-template-rows: auto; grid-column-gap: 20px; } .header .content .sidebar1 .sidebar2 .footer { { { { { grid-column: grid-column: grid-column: grid-column: grid-column: 1 2 1 3 1 / / / / / 4; 3; 2; 4; 4; } grid-row: grid-row: grid-row: grid-row: 2 2 2 3 / / / / 3; 3; 3; 4; } } } }

Slide 38

Slide 38

Explicit or implicit Grid Lines • Explicit lines are specified using grid-template-rows or gridtemplate-columns • Implicit lines are created when you place elements into a row or column track OUTSIDE of the explicit grid • Default behaviour = auto sized • You can specify a size with the grid-auto-columns and gridauto-rows properties

Slide 39

Slide 39

60 90 90 60 .grid—4 { grid-template-columns: 60px 60px; grid-template-rows: 90px 90px; }

Slide 40

Slide 40

60 60 0 0 auto .grid—4 { grid-template-columns: 60px 60px; grid-template-rows: 90px 90px; } 90 .grid__item—1 { grid-column: 1 / 2; grid-row: 2 / 3; } 90 .grid__item—2 { grid-column: 5 / 6; grid-row: 2 / 3; } 1 2

Slide 41

Slide 41

60 60 60 60 auto 90 90 .grid—4 { grid-template-columns: 60px 60px; grid-template-rows: 90px 90px; grid-auto-columns: 60px; } .grid__item—1 { grid-column: 1 / 2; grid-row: 2 / 3; } 1 2 .grid__item—2 { grid-column: 5 / 6; grid-row: 2 / 3; }

Slide 42

Slide 42

Auto-flow • If you have items not placed in an explicit grid - > auto-flow • Row: fill each row in turn, then add more rows • Column: fill each column in turn, then add more columns • Dense: try to fill holes earlier in the grid (might change order) .grid—5 { grid-auto-flow: row | column | row dense | column dense; }

Slide 43

Slide 43

Auto-flow 2 3 4 5 1 6 .grid—5 { grid-auto-flow: row; } Row: fill each row in turn, then add more rows

Slide 44

Slide 44

Auto-flow 2 4 5 1 3 6 .grid—5 { grid-auto-flow: column; } Column: fill each column in turn, then add more columns

Slide 45

Slide 45

Grid is kinda like <table> • But does not rely on content source order • Semantic • Can move items around with breakpoints Grid item placement and reordering must not be used as a substitute for correct source ordering, as that can ruin the accessibility of the document.

Slide 46

Slide 46

Alignment

Slide 47

Slide 47

justify-items .grid—6 { justify-items: start; }

Slide 48

Slide 48

justify-items .grid—6 { justify-items: end; }

Slide 49

Slide 49

justify-items .grid—6 { justify-items: center; }

Slide 50

Slide 50

justify-items .grid—6 { justify-items: stretch; }

Slide 51

Slide 51

align-items .grid—6 { align-items: start; }

Slide 52

Slide 52

align-items .grid—6 { align-items: end; }

Slide 53

Slide 53

align-items .grid—6 { align-items: center; }

Slide 54

Slide 54

align-items .grid—6 { align-items: stretch; }

Slide 55

Slide 55

justify-content .grid—6 { justify-content: start; }

Slide 56

Slide 56

justify-content .grid—6 { justify-content: end; }

Slide 57

Slide 57

justify-content .grid—6 { justify-content: center; }

Slide 58

Slide 58

justify-content .grid—6 { justify-content: stretch; }

Slide 59

Slide 59

justify-content .grid—6 { justify-content: space-around; }

Slide 60

Slide 60

justify-content .grid—6 { justify-content: space-between; }

Slide 61

Slide 61

justify-content .grid—6 { justify-content: space-evenly; }

Slide 62

Slide 62

align-content .grid—6 { align-content: start; }

Slide 63

Slide 63

align-content .grid—6 { align-content: end; }

Slide 64

Slide 64

align-content .grid—6 { align-content: center; }

Slide 65

Slide 65

align-content .grid—6 { align-content: stretch; }

Slide 66

Slide 66

align-content .grid—6 { align-content: space-around; }

Slide 67

Slide 67

align-content .grid—6 { align-content: space-between; }

Slide 68

Slide 68

align-content .grid—6 { align-content: space-evenly; }

Slide 69

Slide 69

Naming things

Slide 70

Slide 70

As we remember… .grid__item—1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 2; } A .grid__item—1 { grid-column: 1 / 3; grid-row: 1 / 2; } .grid__item—1 { grid-area: 1 / 1 / 3 / 2; }

Slide 71

Slide 71

Spanning cells A .grid__item—1 { grid-column: 1 / 3; grid-row: 1; // defaults to span 1 }

Slide 72

Slide 72

Span keyword A .grid__item—1 { grid-column: 1 / span 2; grid-row: 1; }

Slide 73

Slide 73

Named lines .grid—5 { grid-template-columns: grid-template-rows: A } [col1-start] [col2-start] [col3-start] [col3-end]; [row1-start] [row2-start] [row2-end]; .grid__item—1 { grid-column: col1-start / col3-start; grid-row: row1-start; } 100px 100px 100px auto auto

Slide 74

Slide 74

Named lines with span .grid—5 { grid-template-columns: grid-template-rows: A } [col] 100px [col] 100px [col] 100px [col]; [row] auto [row] auto [row]; .grid__item—1 { grid-column: col / span 2; grid-row: row; }

Slide 75

Slide 75

Repeat keyword A .grid—5 { grid-template-columns: repeat(3, [col] 100px); grid-template-rows: repeat(2, [row] auto); } .grid__item—1 { grid-column: col / span 2; grid-row: row; }

Slide 76

Slide 76

Defining Grid Areas Header Sidebar // SCSS .grid—5 { grid-template-columns: 120px 120px grid-template-areas: “……. header header” “sidebar content content”; } 120px; .header { grid-area: header; } .sidebar { grid-area: sidebar; } .content { grid-area: content; } Content <!— HTML —> <div class=”grid grid—5”> <div class=”grid__item header”>Header</div> <div class=”grid__item sidebar”>Sidebar</div> <div class=”grid__item content”>Content</div> </div>

Slide 77

Slide 77

Grids within grids

Slide 78

Slide 78

Nested grid 1 2 5 3 6 7

<!— HTML —> <div class=”grid grid—8”> <div class=”grid__item grid__item—1”>1</div> <div class=”grid__item grid__item—2”>2</div> <div class=”grid__item grid__item—3”>3</div> <div class=”grid__item grid__item—4”> <div class=”grid__item grid__item—5”>5</div> <div class=”grid__item grid__item—6”>6</div> <div class=”grid__item grid__item—7”>7</div> </div> </div>

Slide 79

Slide 79

// SCSS .grid—8 { grid-gap: 10px; grid-template-columns: repeat(4, [col] 150px); repeat(4, [row] auto); } Nested grid 1 2 5 3 6 7 .grid-item—1 { grid-column: } .grid-item—2 { grid-column: } .grid-item—3 { grid-column: } .grid-item—4 { grid-column: } col / span 2; grid-row: row; col 3 / span 2; grid-row: row; col / span 2; grid-row: row 2; col 3 / span 2; grid-row: row 2;

Slide 80

Slide 80

.grid-item—4 { grid-column: col 3 / span 2; grid-row: row 2; display: grid; grid-gap: 10px; grid-template-columns: 1fr 1fr; } Nested grid 1 2 .grid-item—5 { grid-column: 1 / 3; grid-row: 1; } 5 .grid-item—6 { grid-column: 1; grid-row: 2; } 3 6 7 .grid-item—7 { grid-column: 2; grid-row: 2; }

Slide 81

Slide 81

.grid-item—4 { grid-column: col 3 / span 2; grid-row: row 2; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; } Subgrid 1 2 5 3 6 7

Slide 82

Slide 82

Subgrid “The following feature are at-risk, and may be dropped during the CR period: the subgrid value of grid-template-columns and grid-template-rows, and it’s component parts individually”

Slide 83

Slide 83

Resources • http://gridbyexample.com/ • https://www.youtube.com/watch?v=GRexIOtGhBU • http://www.slideshare.net/rachelandrew/css-grid-layout-for-topconf-linz • http://www.thedotpost.com/2015/12/rachel-andrew-the-new-css-layout • https://css-tricks.com/snippets/css/complete-guide-grid/ • https://hacks.mozilla.org/2015/09/the-future-of-layout-with-css-grid-layouts/ • http://igalia.github.io/css-grid-layout/index.html • https://github.com/FremyCompany/css-grid-polyfill • https://medium.com/@patrickbrosset/css-grid-layout-6c9cba6e8a5a#.ls5y5g53h

Slide 84

Slide 84

Thank You