Dynamic CSS Layouts & Beyond
Dynamic CSS Layouts & Beyond
FullStackFest — August 21, 2018
OddBird
Full-Stack Client Services
One does not simply “learn” JavaScript
Susy
Susy download numbers are big
Susy, scribbled out
Mission statement…
Let’s Talk About CSS
Let’s Talk About CSS 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
The control which designers know in the print medium, and often desire in the web medium, is simply a function of the limitation of the printed page.
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, scribbled out
.grid-span {
width: span(3);
margin-right: gutter();
padding-left: span(1 wide);
}
Make Code Meaningful
(To humans &&
machines)
Make your code do more.
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
2012: Flexbox
Chrome 21
Flexbox line-wrapping
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: 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
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!
Grid columns and 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 |
Daniela Vázquez (@d4tagirl) data visualization at CSS Conf Argentina
index | value |
---|---|
0 | 9 |
1 | 55 |
2 | 59 |
3 | 55 |
4 | 48 |
5 | 99 |
6 | 96 |
7 | 48 |
8 | 11 |
9 | 99 |
10 | 3 |
11 | 35 |
12 | 62 |
13 | 60 |
14 | 84 |
name | x value | y value | size == z value |
---|---|---|---|
item-0 | 34 | 36 | 10 |
item-1 | 35 | 29 | 1 |
item-2 | 72 | 68 | 18 |
item-3 | 98 | 63 | 23 |
item-4 | 33 | 5 | 2 |
item-5 | 80 | 96 | 11 |
item-6 | 65 | 96 | 7 |
item-7 | 18 | 33 | 3 |
item-8 | 24 | 83 | 2 |
item-9 | 98 | 23 | 5 |
item-10 | 81 | 23 | 4 |
item-11 | 35 | 64 | 2 |
item-12 | 99 | 15 | 0 |
item-13 | 20 | 42 | 8 |
item-14 | 2 | 73 | 9 |
item-15 | 13 | 58 | 8 |
item-16 | 95 | 90 | 12 |
item-17 | 13 | 47 | 4 |
item-18 | 19 | 97 | 20 |
item-19 | 3 | 17 | 17 |
???
Levitated Toy Factory at Beyond Tellerand
Movement Demos by Mauricio Palma
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]