CSS Typed OM Reference

CSSNumericValue, CSSKeywordValue, CSSStyleValue types with parse and compute methods

Reference for the CSS Typed Object Model (Houdini) — CSSStyleValue, CSSUnitValue, CSSMathSum, CSSKeywordValue, CSSTransformValue and the attributeStyleMap/computedStyleMap APIs — with creation, arithmetic and unit conversion. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What problem does CSS Typed OM solve?

The classic CSSOM exposes styles as strings, so reading element.style.width gives '100px' that you must parse and re-stringify. Typed OM exposes values as typed objects like CSSUnitValue { value: 100, unit: 'px' }, so you read .value as a number, do arithmetic, and write back without error-prone string concatenation.

The CSS Typed Object Model, part of Houdini, replaces stringly-typed style access with real typed objects. This reference covers the value types and the style-map APIs.

How it works

Instead of strings, styles are objects with numeric fields:

// old CSSOM — strings
el.style.width;                 // "100px"  → must parse

// Typed OM — objects
el.computedStyleMap().get("width");      // CSSUnitValue { value: 100, unit: "px" }
el.attributeStyleMap.set("width", CSS.px(100));

The base class is CSSStyleValue. Concrete subtypes include CSSUnitValue (a number + unit), CSSKeywordValue (an identifier like auto), CSSMathSum/CSSMathProduct (calc expressions), CSSTransformValue and CSSColorValue. The CSS.px(...), CSS.percent(...), CSS.deg(...) and CSS.number(...) factories build unit values directly.

Arithmetic and conversion

CSSNumericValue supports add, sub, mul, div, min, max:

  • Compatible units reduce to a single CSSUnitValueCSS.px(10).add(CSS.px(5))15px.
  • Incompatible units stay symbolic — CSS.px(10).add(CSS.percent(50)) → a CSSMathSum (a calc()), because the result cannot be resolved without layout.
  • .to(unit) converts within a unit family (e.g. CSS.cm(1).to("mm")10mm).

Read computed values with the read-only element.computedStyleMap(); read/write inline values with element.attributeStyleMap. Feature-detect with "computedStyleMap" in Element.prototype.


Type reference at a glance

TypeWhat it representsExample factory
CSSUnitValueA number with a CSS unitCSS.px(100), CSS.percent(50)
CSSKeywordValueA CSS keyword identifiernew CSSKeywordValue('auto')
CSSMathSumA calc(a + b) expressionCSS.px(10).add(CSS.percent(5))
CSSMathProductA calc(a * b) expressionCSS.px(10).mul(2)
CSSMathNegateA negated valueCSS.px(10).negate()
CSSTransformValueA list of transform functionsnew CSSTransformValue([...])
CSSStyleValueThe root type for all above(abstract — use subtypes)

Reading and writing styles with style maps

Two maps are available on elements, serving different purposes:

// attributeStyleMap — equivalent to the inline style attribute
// Read/write; reflects only explicitly set inline styles
el.attributeStyleMap.set('opacity', CSS.number(0.5));
el.attributeStyleMap.get('opacity'); // CSSUnitValue { value: 0.5, unit: 'number' }
el.attributeStyleMap.delete('opacity');

// computedStyleMap() — equivalent to getComputedStyle()
// Read-only snapshot; reflects the final resolved value after cascade + inheritance
const map = el.computedStyleMap();
map.get('font-size');   // e.g. CSSUnitValue { value: 16, unit: 'px' }
map.get('display');     // CSSKeywordValue { value: 'block' }

A key difference from getComputedStyle: computedStyleMap() returns typed objects, so you can immediately do arithmetic on the .value property rather than parsing a string with parseFloat.

Practical example — animated width from current computed value

A common animation pattern: read the current computed width, then increment it without string parsing:

const map = el.computedStyleMap();
const currentWidth = map.get('width');    // CSSUnitValue, e.g. { value: 200, unit: 'px' }
const newWidth = currentWidth.add(CSS.px(50));  // CSSUnitValue { value: 250, unit: 'px' }
el.attributeStyleMap.set('width', newWidth);

Compare this to the old approach: parseFloat(getComputedStyle(el).width) + 50 + 'px' — three string operations that can produce NaN silently if the value is unexpectedly not a plain pixel length.

When to use CSS Typed OM

Typed OM is most useful in JavaScript-driven animation loops, canvas-synchronized layouts, and CSS Houdini Paint/Layout worklets where you are reading and writing many style values in rapid succession. For simple one-shot style changes, the string API is often adequate and more broadly supported. Always feature-detect before relying on computedStyleMap in production code.