A presentation at Front-end Day at Making Waves in April 2016 in Oslo, Norway by Ronny Siikaluoma
THE GRID The future of CSS layout
Evolution of web layout
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
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
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
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
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
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
// 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
View The Grid - The Future of CSS Layout on Notist.
Dismiss
A walkthrough of the CSS Grid Layout Module Specification as of April 2016