Breaking out from the CSS straitjacket
Worklets
CSS Typed OM + Properties & Values API
Layout API
Paint API
Animation Worklet
https or localhost
Parse
DOM
CSSOM
Cascade
Layout
Paint
Composition
Properties &
Values API
Layout API
Paint API
Animation
Worklet
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
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
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
Paint API
Animation
Worklet
Typed OM
Worklets
CSS.registerProperty({
name: '',
inherits: true,
syntax: '*',
initialValue: ''
});
:root {
--bg-color: teal;
}
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
@property --bg-color {
syntax: '<color>';
initial-value: coral;
inherits: true;
}
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
CSS.paintWorklet
CSS.layoutWorklet
CSS.animationWorklet
AudioWorklet
CSS.paintWorklet.addModule('paint-worklet.js');
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
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
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
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
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
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
Properties &
Values API
Paint API
Animation
Worklet
Typed OM
Worklets
Layout API