Dynamic CSS with CSS Object Model in JavaScript
The CSS Object Model (CSSOM) is an application programming interface (API) that represents CSS styles as a structured tree of JavaScript objects. This article explains how the CSSOM enables developers to dynamically inspect, insert, modify, and delete stylesheets and individual style rules at runtime using JavaScript, providing a more performant and programmatic alternative to standard inline styling.
Understanding the CSSOM Interface
When a browser loads a webpage, it parses the HTML into the Document
Object Model (DOM) and the CSS into the CSS Object Model (CSSOM). While
the DOM represents the page structure, the CSSOM represents the
associated styling rules. JavaScript can access the CSSOM globally via
the document.styleSheets collection, which returns an
array-like StyleSheetList containing all
<link> and <style> elements
attached to the document.
Reading Styles and Rules
To read existing style rules, you traverse the
document.styleSheets collection and access individual rule
lists:
// Access the first stylesheet in the document
const sheet = document.styleSheets[0];
// Access the list of CSS rules inside the stylesheet
const rules = sheet.cssRules || sheet.rules;
// Read the selector and styling of the first rule
console.log(rules[0].selectorText); // e.g., "body"
console.log(rules[0].style.backgroundColor);For elements whose styles are calculated through the cascade,
inheritance, or external stylesheets, the
window.getComputedStyle(element) method reads the final,
computed properties applied by the browser.
Writing and Modifying Stylesheets
The CSSOM provides explicit methods to alter rules without directly manipulating the HTML DOM:
Inserting Rules: The
insertRule()method adds a new CSS rule to a stylesheet at a specified index.sheet.insertRule('.dynamic-class { color: red; font-size: 16px; }', sheet.cssRules.length);Deleting Rules: The
deleteRule()method removes a rule at a given index.sheet.deleteRule(0); // Removes the first ruleModifying Existing Properties: You can update properties within existing rules using the
styleobject or thesetProperty()method:rules[0].style.setProperty('background-color', '#f0f0f0');
Constructable Stylesheets
Modern browsers also support Constructable Stylesheets via the
CSSStyleSheet constructor, allowing developers to create
and share styles across multiple components (such as Shadow DOM trees)
efficiently:
// Create a new stylesheet
const dynamicSheet = new CSSStyleSheet();
// Apply CSS text synchronously
dynamicSheet.replaceSync('p { line-height: 1.5; color: #333; }');
// Adopt the stylesheet to the document or a shadow root
document.adoptedStyleSheets = [...document.adoptedStyleSheets, dynamicSheet];Advantages of CSSOM Manipulation
Manipulating styles via the CSSOM rather than altering inline styles on individual DOM nodes improves rendering performance and maintainability. When you modify a single CSSOM rule, the browser applies that change across every matching element simultaneously, avoiding repetitive DOM updates and reducing layout thrashing.