W3docs

Working with Styles in the DOM

Learn how to style DOM elements in JavaScript: inline styles, the style property and cssText, reading values with getComputedStyle, and toggling CSS classes.

When working with the Document Object Model (DOM) in JavaScript, changing how an element looks at runtime is one of the most common tasks. This guide covers the practical ways to apply styles to DOM elements: writing inline styles, reading and setting individual CSS properties through the style property, replacing many properties at once with cssText, reading the resolved styles with getComputedStyle(), and — the recommended approach for most cases — toggling CSS classes with the classList API.

The short version: prefer classes over inline styles. Direct style manipulation is fine for values you compute at runtime (a position, a dynamically chosen color), but for anything that represents a state — "active", "completed", "error" — define a class in CSS and toggle it from JavaScript. This guide shows both, then explains when each one is the right tool. For the broader picture of element styling, see Styles and Classes.

Inline Styles

Inline styles apply CSS directly to an HTML element through its style attribute. They are useful for quick, one-off changes, but they don't scale: they mix presentation into your markup, they can't be reused, and they win every specificity battle except !important, which makes them hard to override later.

Example

<div id="inlineStyleExample">This text will be styled using inline styles.</div>
<button onclick="applyInlineStyle()">Apply Inline Style</button>

<script>
  function applyInlineStyle() {
    const element = document.getElementById('inlineStyleExample');
    element.style.color = 'red';
    element.style.fontSize = '20px';
  }
</script>

In this example, clicking the button will apply inline styles to the div element, changing its text color to red and font size to 20 pixels.

Setting Styles Using the style Property

The style property gives you a CSSStyleDeclaration object that maps to the element's inline style. Reading and writing it is the JavaScript equivalent of editing the style attribute — so it shares the same trade-offs as inline styles, but lets you compute values dynamically.

Two rules trip people up:

  • CSS property names become camelCase. Hyphenated properties like font-size and background-color become style.fontSize and style.backgroundColor. The one exception is float, which is style.cssFloat because float is a reserved word.
  • Values are strings, with units. element.style.width = 200 does nothing; you must write element.style.width = '200px'. Likewise, reading element.style.color after setting it gives you back a string such as 'rgb(0, 0, 255)'.

Example

<div id="stylePropertyExample">This text will be styled using JavaScript.</div>
<button onclick="applyStyleProperty()">Apply Style Property</button>

<script>
  function applyStyleProperty() {
    const element = document.getElementById('stylePropertyExample');
    element.style.color = 'blue';
    element.style.fontSize = '18px';
    element.style.margin = '10px';
  }
</script>

In this example, clicking the button will apply several styles to the div element using the style property. The text color is set to blue, the font size to 18 pixels, and a margin of 10 pixels is added.

Setting many properties at once with cssText

Assigning one property at a time triggers a separate write each time. When you need to set several properties together, style.cssText lets you assign them in a single statement using ordinary CSS syntax:

element.style.cssText = 'color: white; background-color: navy; padding: 8px;';

Be aware that assigning cssText replaces all existing inline styles, so use it to set a complete block rather than to tweak one value. To remove a single property, set it to an empty string (element.style.color = '') or call element.style.removeProperty('color').

Reading the actual style with getComputedStyle()

The style property only reflects inline styles. If a color comes from a stylesheet or a class, element.style.color is an empty string. To read the value the browser actually applied — after stylesheets, classes, and inheritance are resolved — use window.getComputedStyle():

<p id="styledByCss">I am styled by a stylesheet.</p>
<button onclick="readStyle()">Read computed color</button>

<script>
  function readStyle() {
    const element = document.getElementById('styledByCss');
    // element.style.color would be '' — the color comes from CSS, not inline.
    const computed = window.getComputedStyle(element);
    alert('Computed color: ' + computed.color);
  }
</script>

<style>
  #styledByCss {
    color: green;
  }
</style>

Computed values are returned in a normalized, read-only form — colors as rgb(...), lengths in px — so getComputedStyle(element).color returns 'rgb(0, 128, 0)' rather than 'green'.

Class Manipulation

Managing classes is the recommended way to style elements: the styling lives in your CSS, and JavaScript only flips classes on and off. The classList property exposes a small, well-named API — add(), remove(), toggle(), contains(), replace(), and item() — that is clearer and safer than building strings with className.

Why prefer classList over className? Writing element.className = 'highlight' overwrites every existing class, so you can accidentally drop classes another part of your code relies on. classList.add('highlight') adds just that one class and leaves the rest untouched.

Adding Classes

The add() method adds one or more classes to an element. Adding a class that is already present does nothing, so it is safe to call repeatedly.

Example

<div id="addClassExample">This element will have classes added.</div>
<button onclick="addClass()">Add Class</button>

<script>
  function addClass() {
    const element = document.getElementById('addClassExample');
    element.classList.add('highlight', 'text-large');
  }
</script>

<style>
  .highlight {
    background-color: yellow;
  }

  .text-large {
    font-size: 24px;
  }
</style>

In this example, clicking the button will add the classes highlight and text-large to the div element, applying the corresponding styles.

Removing Classes

The remove() method removes one or more classes from an element. Removing a class that isn't there is a no-op, so you don't need to check first.

Example

<div id="removeClassExample" class="highlight text-large">
  This element will have classes removed.
</div>
<button onclick="removeClass()">Remove Class</button>

<script>
  function removeClass() {
    const element = document.getElementById('removeClassExample');
    element.classList.remove('highlight', 'text-large');
  }
</script>

<style>
  .highlight {
    background-color: yellow;
  }

  .text-large {
    font-size: 24px;
  }
</style>

Here, clicking the button will remove the highlight and text-large classes from the div element.

Toggling Classes

The toggle() method adds a class if it is not present and removes it if it is — perfect for on/off states such as a menu being open or a task being completed. It returns true if the class is present afterward and false otherwise.

You can also force the result with a second boolean argument: toggle('active', true) always adds the class, and toggle('active', false) always removes it. This is handy when the desired state comes from a variable: element.classList.toggle('active', isActive).

Example

<div id="toggleClassExample">Click me to toggle the highlight class.</div>
<button onclick="toggleClass()">Toggle Class</button>

<script>
  function toggleClass() {
    const element = document.getElementById('toggleClassExample');
    element.classList.toggle('highlight');
  }
</script>

<style>
  .highlight {
    background-color: yellow;
  }

  .text-large {
    font-size: 24px;
  }
</style>

In this example, clicking the button will toggle the highlight class on and off on the div element.

Checking for Classes

The contains() method returns true if an element has a specific class and false otherwise. Use it to branch on the current state, for example to update a button's label.

Example

<div id="containsClassExample" class="highlight">
  This element's classes will be checked.
</div>
<button onclick="checkClass()">Check Class</button>

<script>
  function checkClass() {
    const element = document.getElementById('containsClassExample');
    if (element.classList.contains('highlight')) {
      alert('The element has the highlight class.');
    } else {
      alert('The element does not have the highlight class.');
    }
  }
</script>

<style>
  .highlight {
    background-color: yellow;
  }

  .text-large {
    font-size: 24px;
  }
</style>

Here, clicking the button will check if the containsClassExample element has the highlight class and display an alert accordingly.

Replacing a Class

The replace() method swaps one class for another in a single call and returns true if the old class existed and was replaced. It is cleaner than calling remove() then add():

<div id="replaceClassExample" class="theme-light">Switch my theme.</div>
<button onclick="swapTheme()">Toggle theme</button>

<script>
  function swapTheme() {
    const element = document.getElementById('replaceClassExample');
    if (!element.classList.replace('theme-light', 'theme-dark')) {
      // It wasn't 'theme-light', so swap the other way.
      element.classList.replace('theme-dark', 'theme-light');
    }
  }
</script>

<style>
  .theme-light { background: #fff; color: #111; padding: 8px; }
  .theme-dark { background: #111; color: #fff; padding: 8px; }
</style>

classList is also iterable, and classList.item(index) returns the class at a given position (or null if the index is out of range), which is occasionally useful when you need to read the classes one by one.

Real-World Example: Interactive To-Do List

To demonstrate these concepts in a real-world scenario, let's build a small interactive to-do list. New tasks are added to the list, and clicking a task toggles a completed class that strikes it through — a textbook case for classList.toggle().

<div>
  <h2>To-Do List</h2>
  <p>Here, you can add new items, and mark it as completed by clicking on them.</p>
  <input type="text" id="newTask" placeholder="Add a new task" />
  <button id="addTaskButton">Add Task</button>
  <ul id="taskList"></ul>
</div>

<script>
  const newTaskInput = document.getElementById('newTask');
  const addTaskButton = document.getElementById('addTaskButton');
  const taskList = document.getElementById('taskList');

  addTaskButton.addEventListener('click', () => {
    const taskText = newTaskInput.value;
    if (taskText) {
      const taskItem = document.createElement('li');
      taskItem.textContent = taskText;
      taskItem.classList.add('task');

      taskItem.addEventListener('click', () => {
        taskItem.classList.toggle('completed');
      });

      taskList.appendChild(taskItem);
      newTaskInput.value = '';
    }
  });
</script>

<style>
  .task {
    cursor: pointer;
    padding: 5px;
    border-bottom: 1px solid #ccc;
  }

  .task.completed {
    text-decoration: line-through;
    color: gray;
  }
</style>

In this example, we create a to-do list application where tasks can be added and marked as completed by clicking on them. The task class styles the tasks, while the completed class, applied using the toggle() method, indicates completed tasks.

Best Practices

To ensure efficient and maintainable code when working with styles in the DOM, consider the following best practices:

  1. Separation of Concerns: Keep your HTML, CSS, and JavaScript separate. Use JavaScript to manipulate classes rather than setting styles directly whenever possible. This approach maintains the separation of concerns and makes your code easier to manage.
  2. Avoid Inline Styles: Use inline styles sparingly. Inline styles can make your HTML cluttered and harder to maintain. Instead, prefer adding and removing classes that are defined in your CSS.
  3. Use Classes for Reusability: Define reusable classes in your CSS and use JavaScript to toggle these classes. This approach allows for more consistent styling across your application and makes it easier to update styles.
  4. Leverage classList Methods: Use the classList methods (add, remove, toggle, contains) to manage classes efficiently. These methods are straightforward and perform well compared to manipulating the className property directly.
  5. Performance Considerations: Be mindful of performance when manipulating the DOM. Toggling a single class triggers one set of style recalculations, whereas setting many properties one at a time on element.style can cause repeated reflows. For deeper guidance, see DOM Performance Optimization.
Info

Prefer CSS transitions and animations over JavaScript-driven animation loops. Toggle a class and let the browser animate the change — it runs on the compositor and is usually smoother. See CSS Animations for the details.

Conclusion

Manipulating styles in the DOM is essential for dynamic, interactive interfaces. Use the style property (and cssText) for values you compute at runtime, getComputedStyle() to read the styles the browser actually applied, and the classList API — add, remove, toggle, contains, replace — for everything that represents a reusable state. As a rule of thumb, reach for classes first and inline styles only when you must.

To keep building on the DOM, explore DOM Manipulation, Selecting DOM Elements, and Attributes and Properties.

Practice

Practice
Which classList method adds one or more classes without removing the existing ones?
Which classList method adds one or more classes without removing the existing ones?
Practice
You set element.style.width = 200 and nothing changes. Why?
You set element.style.width = 200 and nothing changes. Why?
Practice
How do you read the color the browser actually applied to an element when it comes from a stylesheet?
How do you read the color the browser actually applied to an element when it comes from a stylesheet?
Was this page helpful?