THE GRID The future of CSS layout

Evolution of web layout

<table>

float

display: inline-block

display: table

position: absolute

CSS Frameworks

display: flex

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.)

display: grid

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

Browser support

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

The basics

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>

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

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

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

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

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

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; }

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

Terminology

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

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

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

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

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

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

Movin’ on

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

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

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

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

«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; } } } }

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; } } } }

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

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

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

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; }

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; }

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

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

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.

Alignment

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Naming things

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; }

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

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

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

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; }

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; }

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>

Grids within grids

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>

// 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;

.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; }

.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

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”

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

Thank You