Don’t Use My Grid System The Past & Future of Web Layout
Don’t Use My Grid System The Past & Future of Web Layout
Covalence Conference — January 16, 2019
ES6 Modules in Electron
Web Layouts in Electron
Hi, my name is Miriam, and I’ve never used Electron.js
Ok, so I use it every day…
OddBird
Full-Stack Consulting Agency
Jessica Lord: Nativize is the New Normalize
CSS Layout
Susy
No Susy
The End!
Damn, that was easy…
1993: HTML
Markup Language
OddBird siblings (Jonny, Carl, and Miriam) in 1994
1997: <table>
HTML 3.2
(╯'□')╯︵
┻━┻
“TABLES ARE FOR DATA”
👎
Limited Styling
👎
Strict (non-linear) Markup
👎
Accessibility Nightmare
“Code is Communication”
—Sarah Drasner *
* (once)
Table Layouts Destroy Meaning
for both humans and machines…
1996 2000: Cascading Style Sheets
Principle of Least Power
(This is a Feature)
don’t be fooled…
Declarative Syntax !=
Static Results
Dynamic Relationships
how is this going to change…?
…when the content changes?
…when the viewport changes?
…when the context changes?
A zillion different devices of all sizes (original)
! 👨
Masculine emojis
Feminine emojis
Various people emojis
Go with the flow!
Classic Layouts…
Position?
Relative positions have no effect on flow
Absolute positions remove from flow
Absolute (or Fixed) For Overlays Only
off-canvas, drop-downs, tooltips, modals, etc…
Floats?
float:
left
// float:
right
Great for elements that should… float…
Requires ClearFix (Hack)
apply to any container element…
// "Micro" Clearfix Mixin
@mixin clearfix {
&::after {
clear: both;
content: ' ';
display: table;
}
}
// "Micro" Clearfix Class
.clearfix::after { /* same… */ }
display:
flow-root
the new clearfix alternative, with very little support…
👍
Flexible Markup & Nesting!
👎
Explicit Widths
floats aren’t very smart about context…
¯\_(ツ)_/¯
not the worst hacks…
Display: Table?
No Margins, Use border-padding
2007-2010: Major Grid Frameworks
Blueprint, OOCSS, 960gs, Susy, etc…
12 column grid, single axis
Span some of those columns!
Add a gutter on the right margin…
Remove the last margin in a row…
Classes Are The API
class="
column col6of12 last
"
960gs uses “split” gutters to avoid last
…
👍
Provide Consistent Patterns
and take care of all the hacks…
👍
Developers Can Ignore CSS
👎
Developers Will Ignore CSS
👎
One Size Fits No One
CSS Systems by Natalie Downe
- Systems > Frameworks
- Fluid Grids
- Static (
px
) | Elastic (em
) Containers
👍
“Responsive” before Responsive™
Fluid Grid Math Sux
.grid-span {
width: 23.7288136%;
margin-right: 01.6949153%;
padding-left: 08.4745763%;
}
target / context == multiplier
width: percentage(target / context)
Fluid Grid Math Sux
.grid-span {
width: percentage(((3*4em) + (2*1em)) / ((12*4em) + (11*1em))); // 23.7288136%
margin-right: percentage(1em / ((12*4em) + (11*1em))); // 01.6949153%
padding-left: percentage(((1*4em) + (1*1em)) / ((12*4em) + (11*1em))); // 08.4745763%
}
Sass (2006) & Susy (2009)
.grid-span {
width: span(3);
margin-right: gutter();
padding-left: span(1 wide);
}
👍
Any Grid System, On Demand
👎
Usually Overkill
No Susy
Remove Gutters
OOCSS uses fractions to keep math simple…
Fix the Box Model
(IE got it right the first time)
Content-Box: total = width/height
+
borders
+
padding
Border-Box: total = width/height
👍
Global Box-Sizing
* {
box-sizing: border-box;
}
👎
Fragile Box-Sizing
never inherit layout properties!
html {
box-sizing: border-box;
}
* {
box-sizing: inherit;
}
Avoid Tightly Coupled Elements
components respond to unexpected changes
2011: calc()
Firefox 4
Mixed-Unit Calculations
calc(
16px
+
20%
)
2012: Flexbox
Chrome 21
Global Flow
flex-direction: column;
| flex-wrap: wrap;
Individual Sizing
grow, shrink, basis =>
flex: 1 2 auto
;
👍
-Grow
& -Shrink
Define Relationships!
👎
Nesting Matters
👎
Poor Page-Level Performance
2014: --css-
variables
Firefox 31 (unless you count currentColor
)
.example {
--color: red;
background: var(--red);
}
-<empty>-
browser-prefix
--aka
:
'custom properties'
;
var(
--property-name
, fallback)
Sass Variables Scope
Based on Source File Structure
:root { $columns: 2; }
.nested-class { /* $columns == undefined */ }
@media (min-width: 30em) {
:root { /* $columns == undefined */ }
.nested-class { /* $columns == undefined */ }
}
CSS Variables Inherit
Based on DOM & Cascade
:root { --columns: 2; }
.nested-class { /* var(--columns) == 2 */ }
@media (min-width: 30em) {
:root { --columns: 6; }
.nested-class { /* var(--columns) == 6 */ }
}
Inherit Everywhere:
:root {
--brand-color: hsl(330, 100%, 45%);
}
Don’t Inherit:
* {
--brand-color: initial;
}
Safe Inline Styles
<button style="--color: blue;">
Use the Variable…
button {
background: var(--color, red);
}
…or Ignore the Variable
button.green {
background: green;
}
Avoid Nesting…
button {
background: blue
}
.this button {
background: red;
}
…For Lower Specificity
button {
background: var(--btn-color, blue);
}
.this {
--btn-color: red;
}
Combine with calc()
* {
--width: calc(var(--span) / var(--columns) * 100%);
box-sizing: border-box;
width: var(--width, initial);
}
.calc-gutters .item {
--span: 1;
float: left;
padding: var(--gutters);
}
Media Queries…
:root {
--columns: 3;
--gutters: 0.5em;
@media (min-width: 50em) {
--columns: 6;
--gutters: 1em;
}
}
CSSSusy!
:root {
--susy-columns: 1;
--susy-gutters: 0.25;
--susy-spread: -1;
--susy-container-spread: -1;
/* --susy-static-grid: 1; */
/* --susy-debug-color: green; */
}
A Variable for Every Function…
* {
/* gutter output math */
--su-inside-gutters: calc(
var(--gutter-width) * var(--gutters-inside)
);
--su-gutters-left: calc(
var(--gutter-width) * var(--gutters-left)
);
}
AG Grid Nesting Test from OOCSS [permalink / source]
Susy, scribbled out
Viewport Units
vw
, vh
, vmin
, vmax
Full Height…
height:
100vh
Sticky-Footer…
min-height:
100vh
Breaking Out of the Container…
calc(
50% - 50vw
)
2017: Jet Packs*!
*Kinda
2017: CSS Grid
Firefox 52 & Chrome 57 & Safari 10
Nothing Like It
At All
The Spec is Complex…
Getting Started Is Not
Truly Two-Dimensional Layouts
columns & rows! mixed units!
.container {
display: grid;
grid-template-columns: 300px 1fr minmax(30em, 50%) 10vw; /* mixed units! */
grid-template-rows: 300px 300px 300px; /* repeat(3, 300px) */
grid-gap: 10px;
}
Grid-Items: By Line
.one {
grid-column: 1 / 4;
grid-row: 2 / span 2;
}
.two {
grid-column: 2 / -1;
grid-row: 1 / -2;
}
Global Flow && Sizing
With auto
escape-hatch to element flow…
body {
display: grid;
grid-gap: 0.5em;
grid-template-rows: auto 1fr auto;
grid-template-columns: minmax(14em, auto) minmax(0, 1fr);
}
Named Areas
body {
grid-template-areas: 'header header'
'nav main'
'footer footer';
}
h1 { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: footer; }
Single Source of Truth
@media (max-width: 50em) {
body {
grid-template: 'header'
'nav'
'main'
'footer';
}
}
%
=> relative to parent width
vw
=> relative to the viewport
fr
=> relative to available space
1fr
==
minmax(auto, 1fr)
use minmax(0, 1fr)
to allow shrinking
2018: Intrinsic Web Design
Fluid & Fixed
Stages of Squishiness
- fixed
- fluid (
fr
) - fluid-until-fixed (
minmax()
|flex-basis
) - flow (
auto
)
Nested Contexts
flexbox, grid, float, etc…
Expand & Contract Content
justify, wrap, flex, etc…
Media Queries, As Needed
repeat(
auto-fit
, minmax(
20em
,
1fr
))
Data-Driven Layouts
<div style="
--start
: 30;
--duration
: 60;">
Screenshot of schedule grid
Bar Charts
<dl class="chart" style="--scale: 100">
<dt class="date">2000</dt>
<dd class="bar" style="--value: 45">45%</dd>
<dt class="date">2001</dt>
<dd class="bar" style="--value: 100">100%</dd>
<!-- etc… -->
</dl>
```html
.bar {
--start: calc(var(--scale) + 1 - var(--value));
grid-row-start: var(--start);
}
2000 | |
---|---|
2001 | |
2002 | |
2003 | |
2004 | |
2005 | |
2006 | |
2007 | |
2008 | |
2009 |
index | value |
---|---|
0 | 57 |
1 | 38 |
2 | 77 |
3 | 67 |
4 | 66 |
5 | 56 |
6 | 52 |
7 | 98 |
8 | 79 |
9 | 8 |
10 | 21 |
11 | 84 |
12 | 4 |
13 | 16 |
14 | 72 |
name | x value | y value | size == z value |
---|---|---|---|
item-0 | 23 | 21 | 24 |
item-1 | 92 | 84 | 18 |
item-2 | 6 | 62 | 22 |
item-3 | 48 | 89 | 20 |
item-4 | 13 | 30 | 21 |
item-5 | 99 | 3 | 19 |
item-6 | 36 | 97 | 18 |
item-7 | 9 | 47 | 7 |
item-8 | 42 | 74 | 16 |
item-9 | 29 | 50 | 9 |
item-10 | 68 | 11 | 9 |
item-11 | 41 | 85 | 2 |
item-12 | 80 | 24 | 5 |
item-13 | 5 | 89 | 2 |
item-14 | 90 | 73 | 19 |
item-15 | 69 | 91 | 12 |
item-16 | 49 | 82 | 2 |
item-17 | 45 | 19 | 8 |
item-18 | 42 | 27 | 4 |
item-19 | 5 | 7 | 9 |
Levitated Toy Factory at Beyond Tellerand
Rachel Andrew: gridbyexample.com
examples, templates, and fallbacks
Jen Simmons: youtube.com/layoutland
also: labs.jensimmons.com
Inspired by Stacy Kvernmo [permalink / source]