A Practical Overview of the CSS Typed Object Model (Typed OM)

Web designer programming css at a computer

The CSS Typed Object Model (Typed OM) is a modern, object-oriented way to read and write CSS values via JavaScript. It replaces stringly-typed CSS with actual typed objects, making code safer, faster, and easier to reason about.

This post covers what Typed OM is, why it matters, what you can do with it today, and how it compares to traditional DOM/CSSOM approaches.

Why Typed OM?

 Historically, JavaScript interacts with CSS in two main ways:

Typed OM addresses this by:

 The result: fewer bugs from unit mismatches, clearer intent, and potential performance wins.

Practical Use Cases

Performance Considerations

Typed OM aims to reduce parsing/serialization overhead and help engines optimize style updates. However:

Tips and Gotchas

When to Use Typed OM

If you’re doing simple style toggles or class switching, CSS classes and custom properties remain the preferred tools. Typed OM shines when you must compute or inspect styles in JavaScript.
				
					<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Typed OM API Demo</title>
    <link rel="stylesheet" href="style.css">
    <script src="cssTypedObjectModel.js" defer></script>
</head>
<body>
    <h1>CSS Typed OM API Demo</h1>
    <p>Open the browser console to see the typed CSS objects. Click the button to change the box's properties.</p>
    
    <div class="box"></div>
    <br>
    <button id="changeBtn">Animate Box</button>
</body>
</html>
				
			
				
					/* Basic body styling for clarity */
body {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    padding: 2em;
    line-height: 1.6;
}

/* The box we will be manipulating with the Typed OM API */
.box {
    width: 150px;
    height: 150px;
    background-color: steelblue;
    opacity: 0.5;
    /* We add transitions to make the changes visually smooth for the demo */
    transition: width 0.5s ease-in-out, 
                opacity 0.5s ease-in-out,
                transform 0.5s ease-in-out;
}
				
			
				
					// Wait for the DOM to be fully loaded before running the script
document.addEventListener('DOMContentLoaded', () => {
	// Get references to the DOM elements we'll be working with
	const box = document.querySelector('.box');
	const changeBtn = document.getElementById('changeBtn');

	// --- DEMO 1: Reading CSS Properties with Typed OM ---

	// Get the "computed style map" for the element. This is the entry point to the Typed OM.
	// It's like window.getComputedStyle(), but returns typed objects instead of strings.
	const styleMap = box.computedStyleMap();

	// Let's get the 'width' property
	const width = styleMap.get('width');

	// Log the result to the console.
	// Notice it's a CSSUnitValue object, not a string like "150px".
	// This allows for easier and faster manipulation.
	console.log('--- Reading Initial Styles ---');
	console.log("The 'width' property is an object:", width);
	console.log(`Value: ${width.value}, Unit: ${width.unit}`);

	// Let's also get the opacity
	const opacity = styleMap.get('opacity');
	console.log("The 'opacity' property is an object:", opacity);
	console.log(`Value: ${opacity.value}, Unit: ${opacity.unit}`); // CSSMathSum has a different structure

	// --- DEMO 2: Manipulating and Writing CSS Properties ---

	// Add a click event listener to the button to trigger changes
	changeBtn.addEventListener('click', () => {
		console.log('\n--- Button Clicked: Updating Styles ---');

		// Get the current style map again inside the handler
		const currentStyles = box.computedStyleMap();

		// ** Manipulate Width **
		// We can perform math directly on the .value property
		const currentWidth = currentStyles.get('width');
		const newWidthValue = currentWidth.value + 50;

		// ** Manipulate Opacity **
		const currentOpacity = currentStyles.get('opacity');
		const newOpacityValue = currentOpacity.value * 1.5; // Make it more opaque

		// To set styles, we use the 'attributeStyleMap'. This corresponds to the element's 'style' attribute.
		// We use factory functions like CSS.px() and CSS.number() to create the correct typed objects.
		box.attributeStyleMap.set('width', CSS.px(newWidthValue));
		box.attributeStyleMap.set('opacity', CSS.number(newOpacityValue));

		// You can also set properties that weren't there before, like 'transform'
		box.attributeStyleMap.set(
			'transform',
			new CSSTransformValue([
				new CSSTranslate(CSS.px(20), CSS.px(20)),
				new CSSRotate(CSS.deg(45))
			])
		);

		console.log(`Set width to: ${newWidthValue}px`);
		console.log(`Set opacity to: ${newOpacityValue}`);
		console.log('Set a new transform property.');
	});
});

				
			

Summary

The CSS Typed Object Model modernizes JS–CSS interaction with:

Adopt it progressively: check support, lean on Typed OM for complex style logic, and fall back to traditional APIs where necessary. As browser implementations mature, expect Typed OM to become the ergonomic and robust default for programmatic styling.

more posts:
Online video streaming platform and digital content management concept with media player interface, cloud library, and multimedia files on laptop, representing content distribution, video marketing
Code

Breaking into the Pipeline: Real-Time Frame Manipulation with the Insertable Streams for MediaStreamTrack API

The experimental Insertable Streams for MediaStreamTrack API closes a long-standing gap in web multimedia by treating live camera feeds as standard Web Streams. By piping individual VideoFrame objects through a TransformStream and recording the transformed output via MediaRecorder, developers can execute frame-by-frame processing—like real-time filtering, watermarking, and computer vision overlays—without relying on hidden canvas hacks.

Discover More »
Apps & Custom Software

What Building Our Own App Taught Us About Building Yours

When Hess WebTech built and launched Tericipe—an Android app that turns printed recipes into a searchable digital collection—in under three months, we had to live with every decision we usually advise clients on. From testing against real-world messy data and handling AI uncertainty to server-side payment security and post-launch maintenance, here are five crucial lessons from our own build that apply to almost any software project.

Discover More »