Dynamic CSS Layouts & Beyond
Dynamic CSS Layouts & Beyond
CSSConf, AR — August 18, 2018
Intro slide for Andrés
Andrés intro slide, scribbled over with correct details
1993: HTML
Markup Language
OddBird siblings (Jonny, Carl, and Miriam) in 1994
1997: <font>
&&
<table>
HTML 3.2
1996 2000: Cascading Style Sheets
Principle of Least Power
(This is a Feature)
2000: A Dao of Web Design
2007-2010: Major Grid Frameworks
Blueprint, OOCSS, 960gs
OddBird
est. 2008
CSS Systems by Natalie Downe
- Systems > Frameworks
- Fluid Grids
- Static (
px
) | Elastic (em
) Containers
👍
“Responsive” before Responsive™
👎
Ugly Math
target / context * 100%
.grid-span {
width: 23.7288136%;
margin-right: 01.6949153%;
padding-left: 08.4745763%;
}
2009: Compass + Sass
Turing-complete CSS!
.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%
}
Susy
Susy
.grid-span {
width: span(3);
margin-right: gutter();
padding-left: span(1 wide);
}
Make Code Meaningful
(To humans &&
machines)
hsl(330, 100%, 45%)
=> $brand
We’re Naming Things!
“Code is Communication”
—Sarah Drasner *
* (once)
2009: @media
queries
Safari 4
Media Queries title slide from Andrés
2011: calc()
Firefox 4
Mixed-Unit Calculations
calc(
16px
+
20%
)
2011: Responsive Web Design
A zillion different devices of all sizes (from Andrés)
A zillion different devices of all sizes (original)
don’t be fooled…
Declarative Syntax !=
Static Results
Go with the flow!
- Fluid Grids
- Flexible Images
- Media Queries
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)
Similar to Sass…
(but not the same!)
$sass-variables
:
rad
;
Variables Hold Data
$brand: hsl(330, 100%, 45%);
Variables are $reusable
(Don’t Repeat Yourself)
Sass Variables Scope
.example { $columns: 2; }
.nested-class { /* $columns == undefined */ }
@media (min-width: 30em) {
.example { $columns: 6; }
.nested-class { /* $columns == undefined */ }
}
CSS Variables Inherit
.example { --columns: 2; }
.nested-class { /* var(--columns) == 2 */ }
@media (min-width: 30em) {
.example { --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;
}
Defaults & Missing Longhand
.example {
--shadow-y: -1px;
box-shadow: var(--shadow-x, 0)
var(--shadow-y, 1px)
var(--shadow-blur, 0)
var(--shadow-color, currentColor);
}
Auto-Prefixing “Mixins”
* {
--clip-path: initial;
-webkit-clip-path: var(--clip-path);
clip-path: var(--clip-path);
}
Combine with calc()
.example {
margin: calc(1em + var(--extra-margin));
}
AG Grid Nesting Test from OOCSS [permalink / source]
Global Settings…
: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)
);
}
Media Queries…
@media (min-width: 30em) {
/* settings */
:root { --susy-columns: 5; }
/* layout */
[data-susy~='2']{ --span: 1; }
[data-susy~='6'] { --span: 3; }
[data-susy~='6'] * { --susy-columns: 3 }
[data-susy~='3'] { --span: 3; }
[data-susy~='4'] { --span: 2; }
[data-susy~='4'] * { --susy-columns: 2 }
}
Background Images…
main {
background-image: var(--debug-image);
background-size: var(--debug-image-size);
margin: var(--static-gutters) auto;
overflow: hidden;
}
😆
Please Don’t Use It
Manipulate hsl()
Values
* {
--h: 330;
--s: 100%;
--l: 34%;
background: hsl(var(--h), var(--s), var(--l));
}
Use Radial Values to Theme
* {
--darken: calc(var(--l) - 20%);
--complement: calc(var(--h) - 180);
background: hsl(var(--complement), var(--s), var(--darken));
}
Use “Clamped” Values to Toggle
* {
--threshold: 55; /* toggle 'contrast' between white & black */
--contrast: calc((var(--l) - var(--threshold)) * -100%);
color: hsl(var(--h), var(--s), var(--contrast));
}
Inspired by Facundo Corradini [permalink / source]
Tab talking about variable transitions
Animate the property, not the variable
Issues:
- Don’t work inside
url()
=>var(--size)em
calc(var(--size) * 1em)
2017: CSS Grid
Firefox 52 & Chrome 57 & Safari 10
Woman akimbo with helmet and cardboard jet-pack wings
Nothing Like It
At All
The Spec is Complex…
Getting Started Is Not
Defined On Containers
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 10px;
}
Optional Element Control
auto
returns to the flow…
%
=> relative to parent width
vw
=> relative to the viewport
fr
=> relative to remaining space
1fr
==
minmax(auto, 1fr)
use minmax(0, 1fr)
to allow shrinking
Grid lines are 1-indexed
Grid lines are also -1 indexed in reverse
Single Source of Truth
body {
grid-template-areas:
'header header' auto
'nav main' 1fr
'footer footer' auto
/ minmax(14em, auto) minmax(0, 1fr);
}
h1 { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: footer; }
Grid output from grid-area code
2018: Intrinsic Web Design
Fluid & Fixed
Stages of Squishiness
- fixed
fr
units (fluid)minmax()
(fluid until fixed)auto
(flow)
Truly Two-Dimensional Layouts
columns & rows!
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
Daniela talking about data visualization
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>
.bar {
--start: calc(var(--scale) + 1 - var(--value));
grid-row-start: var(--start);
}
2000 | |
---|---|
2001 | |
2002 | |
2003 | |
2004 | |
2005 | |
2006 | |
2007 | |
2008 | |
2009 |
Have Fun!
Inspired by Levitated Toy Factory [permalink / source]
gridbyexample.com
examples, templates, and fallbacks by Rachel Andrew
youtube.com/layoutland
and labs.jensimmons.com by Jen Simmons
Inspired by Stacy Kvernmo [permalink / source]