2 min read

CSS Typed OM (Houdini)

The CSS Typed Object Model (Typed OM) is part of the CSS Houdini project. It provides a way to interact with CSS values as typed JavaScript objects rather than strings.

1. The Problem: String Parsing

Traditionally, reading and writing CSS in JavaScript involved strings.

const element = document.querySelector('.box');
element.style.opacity = "0.5";

// Reading requires parsing
const width = getComputedStyle(element).width; // "100px"
const widthNum = parseInt(width, 10); // 100

This is inefficient (the browser has to serialize to string, JS parses string, then browser parses string back to value) and error-prone.

2. The Solution: Typed Objects

CSS Typed OM exposes CSS values as objects.

  • attributeStyleMap: Replaces element.style.
  • computedStyleMap(): Replaces getComputedStyle(element).
const element = document.querySelector('.box');

// Setting a value
element.attributeStyleMap.set('opacity', 0.5);
element.attributeStyleMap.set('width', CSS.px(200));

// Getting a value
const width = element.computedStyleMap().get('width');
console.log(width); // CSSUnitValue { value: 200, unit: "px" }
console.log(width.value); // 200 (Number!)

3. CSS Numeric Factory Functions

The global CSS object provides factory functions to create units easily.

  • CSS.px(n)
  • CSS.em(n)
  • CSS.rem(n)
  • CSS.deg(n)
  • CSS.percent(n)
element.attributeStyleMap.set('transform', new CSSTransformValue([
  new CSSRotate(CSS.deg(45)),
  new CSSTranslate(CSS.px(10), CSS.px(20))
]));

4. Math Operations

You can perform arithmetic on CSS values, which results in calc() expressions.

const width = new CSSMathSum(CSS.px(100), CSS.em(2));
// Equivalent to: calc(100px + 2em)

element.attributeStyleMap.set('width', width);

5. Performance Benefits

  • Fewer Allocations: Reduces the number of strings created and garbage collected.
  • No Parsing: The browser engine receives the value directly in a format it understands, skipping the CSS parser.
  • Error Handling: Invalid types throw errors immediately in JS, rather than being silently ignored by the CSS parser.

programming/javascript/vanilla/javascript programming/javascript/vanilla/dom-manipulation programming/javascript/vanilla/css-painting-api