Dynamic CSS Layouts & Beyond
Dynamic CSS Layouts & Beyond
JSConf, US — August 21, 2018
Miriam intro (stolen from Jenn)
OddBird
Full-Stack Agency
One does not simply “learn” JavaScript
¯\_(ツ)_/¯
Susy
Susy download numbers are big
Susy, scribbled out
My luggage, flying in for the conference
TSA stole my toothpaste, but the hotel replaced it
Let’s Talk About CSS
Jenn Schiffer on repeating history
1993: HTML
Markup Language
OddBird siblings (Jonny, Carl, and Miriam) in 1994
1997: <font>
&&
<table>
HTML 3.2
(╯'□')╯︵
┻━┻
“TABLES ARE FOR DATA”
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
.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
2011: calc()
Firefox 4
Mixed-Unit Calculations
calc(
16px
+
20%
)
2011: Responsive Web Design
A zillion different devices of all sizes (original)
**!**👨
Masculine emojis
Feminine emojis
Various people emojis
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]
JS getPropertyValue()
& setProperty()
let currentColor = footer.style.getPropertyValue('--color');
footer.style.setProperty('--color', newColor);
One does not simply “learn” JavaScript
Issues:
- Unknown value
type
s (transition known properties, not variables) - Don’t work inside
url()
=>var(--size)em
calc(var(--size) * 1em)
Houdini Properties & Values API *
* Experimental (behind Chrome flag)
CSS.registerProperty({
name: "--brand-color",
syntax: "<color>",
initialValue: "pink",
inherits: true,
});
2017: CSS Grid
Firefox 52 & Chrome 57 & Safari 10
Woman akimbo with helmet and cardboard jet-pack wings
The winning node boat
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
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 |
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]