Upload
morten-rand-hendriksen
View
337
Download
5
Embed Size (px)
Citation preview
CSS GRID CHANGES EVERYTHING (SHIFTING THE WEB LAYOUT PARADIGM)
Morten Rand-Hendriksen | @mor10 | WebCamp Zagreb 2017
mor10.com/wczg2017SLIDES, LINKS, ETC:
@mor10 #CSSGrid #WCZG
Paradigm Shift
Desire Path
Pave the cowpath
To formalize an existing de-facto practice.
Desire Path: A Short History of Web Design
1990
Tim Berners-Lee publishes first ever web page.
1990
Web as
text period
Web as
text period
1990
Håkon Wium Lie proposes Cascading Style Sheets
1994
1990
Web as
text period
1994
Dar
k A
ges
Web as
text period D
ark
Age
s
1990
Lynda Weinman publishes Designing with Web Graphics
1996
1990 1996
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Web as
text period
1994
Dar
k A
ges
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Web as
text period D
ark
Age
s
1990
Jeffrey Zeldman publishes Designing with Web Standards
20031996
1990 20031996
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period
1994
Dar
k A
ges
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period D
ark
Age
s
Wild West period
- Tables Frames Flash
“Pixel-perfect”
1990 20031996 2012
Microsoft releases Windows 8
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period D
ark
Age
s
Wild West period
- Tables Frames Flash
“Pixel-perfect”
1990 20031996 2012
Microsoft proposes CSS Grid Layout
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period D
ark
Age
s
Wild West period
- Tables Frames Flash
“Pixel-perfect”
1990 20031996 2015
display: flex;
2012
1990 20031996 2015
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period
1994
Dar
k A
ges
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Un
cert
ain
ty P
erio
d
meanwhile…
Rachel Andrew @rachelandrew
Jen Simmons @jensimmons
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period D
ark
Age
s
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Un
cert
ain
ty P
erio
d
1990 201720031996 2015
display: grid;
2012
1990 20031996 2015
Web Standards Period
- Floats Clears Blogs
“Web 2.0” CSS layout hell
Web as
text period
1994
Dar
k A
ges
Wild West period
- Tables Frames Flash
“Pixel-perfect”
Un
cert
ain
ty P
erio
d
2017
Web as
Layout Surface
Pave the cowpath
To formalize an existing de-facto practice.
Person behind you
What did I just watch?!?!
https://codepen.io/mor10/full/JrpRyv/
CSS Grid makes the impossible possible
<div class="MomentsGuidePage-capsules"> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummary--hero"></div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div>
2
3
4
8
9
10
5
6
7
1
2
3
4
8
9
10
5
6
7
1
2
3
4
1
2
3
4
8
9
10
5
6
7
1
10 10
2
3
4
8
9
10
5
6
7
1
11
12
14
15
11 1312
10
14
9
10
2 3
4
8
5
6 7
1
15
Since the beginning of (web) time, web layouts have been broken.
We’ve just refined how we break them.
.main-content .sidebar
.container
.main-content
.sidebar
.wrap.wrap { border: 5px solid red; }
.main-content { background: blue; }
.sidebar { background: green; }
.main-content .sidebar
.wrap.wrap { border: 5px solid red; }
.main-content { width: 45%; float: left; background: blue; }
.sidebar { width: 45%; float: right; background: green; }
.main-content .sidebar
.wrap.wrap { border: 5px solid red; }
.main-content { width: 45%; float: left; background: blue; }
.sidebar { width: 45%; float: right; background: green; }
/* Clearfix */ .wrap:after { content: ""; display: table; clear: both; }
.main-content .sidebar
.wrap.wrap { display: flex; justify-content: space-between; border: 5px solid red; }
.main-content { width: 45%; background: blue; }
.sidebar { width: 45%; background: green; }
.main-content .sidebar
.wrap
.other-content
.main-content .sidebar
.wrap
.other-content
.container
.main-content .sidebar
.wrap.wrap { display: flex; justify-content: space-between; border: 5px solid red; }
.container { width: 45%; }
.main-content { background: blue; }
.other-content { background: purple; }
.sidebar { width: 45%; background: green; }
.container
.other-content
This is a hack.
float and flex force us to create HTML clutter in the form of wrappers like the .container element in this example.
.main-content .sidebar
.wrap.container
.other-content
This is web layouts today.
float and flex have been the two only options for creating horizontal layouts resulting in the web suffering from a severe case of Divitis.
.main-content .sidebar
.wrap.container
.other-content
http://getbootstrap.com/css/
Paal Joachim Romdahl on Advanced WordPress Group
Me, every time I build a new site
What if we didn’t have to do this any more…
<div class="MomentsGuidePage-capsules"> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummary--hero"></div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div>
<div class="MomentsGuidePage-capsules"> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummary--hero"></div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div>
<div class="MomentsGuidePage-capsules"> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummary--hero"></div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div> <div class="MomentsCapsuleSummaryGroup"> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> <div class="MomentsCapsuleSummaryGroup-list"> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div> </div>
<div class="MomentsGuidePage-capsules"> <div class="MomentsCapsuleSummary--hero"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> <div class="MomentsCapsuleSummary--portrait"></div> </div>
<ul class="MomentsGuidePage-capsules"> <li class="MomentsCapsuleSummary--hero"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> <li class="MomentsCapsuleSummary"></li> </ul>
Problem:
Current tools for web layout are
content-out and one-dimensional.
Solution:
Two-dimensional layout-in tool to separate content
from presentation.
1
2
3
4
5 6
You, right now
OK, I’m listening…
.site
.page-title
.main-content
.sidebar .footer
.masthead
<div class="site"> <header class="masthead"> </header>
<h1 class="page-title"> </h1>
<main class="main-content"> </main>
<aside class="sidebar"> </aside>
<footer class="footer"> </footer>
</div><!-- .site -->
• Grid container • Grid item • Grid line • Grid cell • Grid track • Grid area • Grid gap
CSS Grid Terminology:
Element containing a grid,
defined by setting display: grid;
Grid container <div class="site"> <header class="masthead"> </header>
<h1 class="page-title"> </h1>
<main class="main-content"> </main>
<aside class="sidebar"> </aside>
<footer class="footer"> </footer>
</div><!-- .site -->
Element that is a direct
descendant of the grid
container.
Grid item <div class="site"> <header class="masthead"> </header>
<h1 class="page-title"> </h1>
<main class="main-content"> </main>
<aside class="sidebar"> </aside>
<footer class="footer"> </footer>
</div><!-- .site -->
Horizontal (row) or
vertical (column) line
separating the grid into
sections.
Grid line
Grid lines are referenced
by number, starting and
ending with the outer
borders of the grid.
Grid line 1
2
3
4
5
6
1 2 3 4 5 6
The intersection between
a grid row and a grid
column. Effectively the
same as a table cell.
Grid cell
Rectangular area between
four specified grid lines.
Grid areas can cover one
or more cells.
Grid area
The space between two or
more adjacent grid lines.
Row tracks are horizontal,
Column tracks vertical.
Grid track
Empty space between grid
tracks (shown in blue).
Commonly called gutters.
Grid gap 1
2
3
4
5
6
1 2 3 4 5 6
The person next to you
I’ll pretend I got that…
1. Define a grid.
2. Place items within the grid.
3. Make world peace.
CSS Grid in a Nutshell:
<div class="site"> <header class="masthead"> </header>
<h1 class="page-title"> </h1>
<main class="main-content"> </main>
<aside class="sidebar"> </aside>
<footer class="footer"> </footer>
</div><!-- .site -->
.masthead
.page-title
.main-content
.sidebar
.footer
.site
<div class="site">
</div><!-- .site -->
.masthead
.page-title
.main-content
.sidebar
.footer
.site
.site
Creates a grid container.
display: grid;
.site
2 fractions 1 fraction each
2fr 1fr 1fr
Draws grid lines. Takes list of length values (em, px, %,
fr, etc.) denoting the distance between each line.
grid-template-columns: 2fr 1fr 1fr;
.site
Fit content
auto
1 fraction
1fr
3 fractions
3fr
Draws grid lines. Takes list of length values (em, px, %,
fr, etc.) denoting the distance between each line.
grid-template-rows: auto 1fr 3fr;
.masthead .page- title
.main- content
.sidebar .footer
.site
Grid items automatically
populate grid from top left
to bottom right based on
HTML source order.
.site1 2 3 4
.masthead
grid-column: 2/4; grid-row: 2/3;
Applied to grid items. Defines the start and end grid lines
for columns and rows.
.site1 2 3 4
Start at column line 2. End at column line 4.
.masthead
grid-column: 2/4; grid-row: 2/3;
.masthead
.masthead
.site1
2
3
4
Start at row line 2. End at row line 3.
grid-column: 2/4; grid-row: 2/3;
.site.site { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: auto 1fr 3fr; }
.masthead { grid-column: 2/4; grid-row: 2/3; }
.page-title { grid-column: 1/4; grid-row: 1/2; }
.main-content { grid-column: 1/2; grid-row: 2/4; }
/* etc etc */
1
2
3
4
1 2 3 4
.page-title
.main-content
.sidebar .footer
.masthead
Naysayer to your left
Looks promising, but remembering what lines to target seems tricky… especially when the site is responsive.
.site
title title title
main
main
header header
sidebar footer
Applied to grid container. Uses a text-based grid map to apply grid
area names to individual cells.
grid-template-areas
.site { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: auto 1fr 3fr; grid-template-areas: "title title title" "main header header" "main sidebar footer"; }
Specifies what grid area the element is placed within.
grid-area: [area-name];
title title title
main
main
header header
sidebar footer
.page-title
.main-content
.sidebar .footer
.masthead
.site.site { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: auto 1fr 3fr; grid-template-areas: "title title title" "main header header" "main sidebar footer"; }
.masthead { grid-area: header; }
.page-title { grid-area: title; }
.main-content { grid-area: main; }
/* etc etc */
.site { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto 1fr 3fr; grid-template-areas: "title title" "main header" "main sidebar"; }
.masthead { grid-area: header; }
.page-title { grid-area: title; }
.main-content { grid-area: main; }
.sidebar { grid-area: sidebar; }
.footer { grid-area: footer; }
@media screen and (min-width: 34em) {
.site { grid-template-columns: 2fr 1fr 1fr; grid-template-areas: "title title title" "main header header" "main sidebar footer"; }
}
.site
.page-title
.main-content
.sidebar .footer
.masthead
.site
.page-title
.main-content
.sidebar
.footer
.masthead
.site
.masthead
.page-title
.main-content
.sidebar
.footer
No grid Two-column grid Three-column grid
Girds are not inherited by
child elements. Instead we
create nested grids.
Nested grids
You, right now
Sooooooo… no more floats and clears?
Use CSS Grid any time you work with two-dimensional layouts.
One more thing
The grid container is a flexible box.
.site { display: grid; grid-template-columns: repeat(6, 10em); grid-gap: 1em; }
.site { display: grid; grid-template-columns: repeat(6, 10em); justify-content: center; grid-gap: 1em; }
.site { display: grid; grid-template-columns: repeat(6, 10em); justify-content: space-between; grid-gap: 1em; }
.site { display: grid; grid-template-columns: repeat(6, 10em); justify-content: space-between; grid-gap: 1em; }
repeat(auto-fit, 10em); repeat(auto-fill, 10em);
Creates as many 10em columns as will fit within the grid container.
Will create empty columns.
grid-template-columns: repeat(auto-fill, 10em);
Creates as many 10em columns as will fit within the grid container.
Does not create empty columns.
grid-template-columns: repeat(auto-fit, 10em);
https://codepen.io/mor10/pen/MEQJbM
Your boss / client
… but older browsers!
http://caniuse.com/#search=grid
Grid is supported in all modern browsers.
The elephants in the room
Internet Explorer 101 and Edge2 lag behind*
1 IE10 uses the original Grid specification. 2 Edge is adopting the modern specification October 17th. * Fun fact: CSS Grid was invented by Microsoft for IE10.
Use feature queries to test for grid support in the current browser.
@supports (display: grid) { … }
Current recommendation:
HOLD ON THERE MORTEN!
Everyone right now
That means the site won’t look the same in all browsers!
If it works here…
… it works here as well!
Forcing sites to look the same across all browsers
is a bad habit.
Responsive Web Design means we’ve been serving up
different layouts for different browsers since 2010.
Progressive Enhancement is Responsive Web Design
in three dimensions.
Accessible mobile-first layouts work well on all screen widths.
Embrace Progressive Enhancement! Use the paved desire paths!
1. Build accessible mobile-first layout without grid.
2. Use mobile-first layout as fallback for all browsers.
3. Use @supports to detect grid support.
4. At the appropriate breakpoint, create layout with grid and grid-areas.
5. Explore new layouts as viewport widens.
CSS Grid: A Practical Approach for Today
More CSS Grid info:
Firefox has a grid inspector!
https://goo.gl/SJmlms
Rachel Andrew’s Grid by Example is doctrine.
https://gridbyexample.com/
Rachel Andrew’s book The New CSS Layout comes out next week.
https://goo.gl/LY6cFy
MDN has exhaustive documentation.
https://goo.gl/8RrH2Y
Mozilla’s CSS Grid Playground is a great place to get the basics.
https://goo.gl/rmbkM5
Mozilla also has a demo site with has exhaustive documentation.
https://goo.gl/wa0Fk9
CSS Tricks has a Complete Guide to CSS Grid.
https://goo.gl/Z01gjF
Kuhn, my theme using CSS grid, is on GitHub to give you ideas.
https://goo.gl/URouSh
Building Production-Ready CSS Grid Layouts Today by yours truly at Smashing Magazine
https://goo.gl/dae838
Free for everyone until October 25th, 2017! https://goo.gl/wyC1Lz
Go build your own Desire Paths.
1. Make it accessible.
2. Make it fancy.
3. Make sure the fancy doesn’t break accessibility.