CSS Houdini
Breaking out from the CSS straitjacket
W3C
TASK
FORCE
FLEXBOX
First Public Draft: 2009
Candidate Recommendation: 2012
GRID
FIRST PUBLIC DRAFT: 2011
CANDIDATE RECOMMENDATION: 2017
CSS spec PROCess
ECMASCRIPT spec PROCess
We can't polyfill css
until now...
the problem is
whoami
Developer
Pontus
Worklets
CSS Typed OM + Properties & Values API
Layout API
Paint API
Animation Worklet
https or localhost
CSS RENDERING
pipeline
Parse
DOM
CSSOM
Cascade
Layout
Paint
Composition
Properties &
Values API
Layout API
Paint API
Animation
Worklet
Typed OM
CSS typed om
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
// old way
el.style.opacity = 0.3;
typeof el.style.opacity; // "string"
// new and shiny
el.attributeStyleMap.set('opacity', '0.5');
typeof el.attributeStyleMap.get('opacity').value; // "number"
// Map-like
el.attributeStyleMap.has('opacity'); // true
el.attributeStyleMap.keys(); // Iterator
el.attributeStyleMap.values(); // Iterator
el.attributeStyleMap.entries(); // Iterator
el.attributeStyleMap.delete('opacity');
el.attributeStyleMap.clear();
Worklets
CSS typed om
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
// attributeStyleMap vs computedStyleMap()
el.attributeStyleMap.get('line-height'); // null
el.computedStyleMap().get('line-height'); // {32, 'px'}
el.attributeStyleMap.set('opacity', 3);
el.attributeStyleMap.get('opacity').value; // 3
el.computedStyleMap().get('opacity').value; // 1
el.attributeStyleMap.set('opacity', 'coral'); // TypeError
const transform = new CSSTransformValue([
new CSSRotate(CSS.deg(0))
]);
el.attributeStyleMap.set('transform', transform);
(function draw() {
requestAnimationFrame(draw);
transform[0].angle.value += 5;
el.attributeStyleMap.set('transform', transform);
})();
Worklets
CSS typed om
Properties &
Values API
Worklets
Paint API
Animation
Worklet
Typed OM
if (window.CSS && CSS.number) {
// Supports CSS Typed Om
}
// types
CSS.px(10);
CSS.em(1.5);
CSS.rem('2');
CSS.deg(180);
CSS.rad(2);
CSS.number('100');
CSS.ms(300);
CSS.vw('10');
CSS.percent(50);
CSS.deg(90).to('rad').value;
// 1.5707963267948966
new CSSMathSum(CSS.vw(100), CSS.px(-10));
// calc(100vw - 10px);
CSS.px(1).add(CSS.px(2));
// {value: 3, unit: 'px'}
CSS.px(200).equals(CSS.px(200));
// true
Properties & Values API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
CSS.registerProperty({
name: '',
inherits: true,
syntax: '*',
initialValue: ''
});
:root {
--bg-color: teal;
}
Properties & Values API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties & Values API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties & Values API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
@property --bg-color {
syntax: '<color>';
initial-value: coral;
inherits: true;
}
Worklets
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
CSS.paintWorklet
CSS.layoutWorklet
CSS.animationWorklet
AudioWorklet
CSS.paintWorklet.addModule('paint-worklet.js');
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
// in JS
if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('tooltip.js');
}
// in CSS
@supports (background: paint(id)) {
/* ... */
}
Worklets
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
// main.js
CSS.paintWorklet.addModule('tooltip-worklet.js');
// styles.css
.tooltip {
border-image-source: paint(tooltip);
}
// tooltip-worklet.js
registerPaint('tooltip', class {
static get inputProperties() {
return [];
}
paint(ctx, geometry, styleMap) {
// paint stuff
}
});
Worklets
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Paint API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Animation Worklet
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Listen for user input, like scroll events!
Animate elements based on that user input
Do it all of the main thread!
Make Parallax Perform
Animation Worklet
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Animation Worklet
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Layout API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
if ('layoutWorklet' in CSS) {
await CSS.layoutWorklet.addModule('my-layout-script.js');
console.log('layout script installed!');
}
// my-layout-script.js
registerLayout('masonry', class {
static get inputProperties() { return ['--foo']; }
static get childrenInputProperties() { return ['--bar']; }
static get childDisplay() { return 'normal'; }
*intrinsicSizes(children, styleMap) {
// Intrinsic sizes code goes here.
}
*layout(space, children, styleMap, edges, breakToken) {
// Layout code goes here.
}
});
/* main.css */
body {
display: layout('masonry');
}
Layout API
Layout API
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Layout API
Future proofing the web
Better performance
Higher fidelity
Links
Examples
Articles
VIDEOS
Thank You! 🤓
houdini-css
By Pontus Lundin
houdini-css
A run through of what CSS Houdini is, why it's important and how it fits into the ecosystem
- 767