Add, remove, and toggle CSS classes with JavaScript

Use the classList API to add, remove, toggle, check, or replace CSS classes on an element. Unlike string manipulation, it handles whitespace and duplicate classes for you.

The element-selection methods used in these examples are covered in this DOM query guide.

Add and remove classes

Select an element, then call classList.add() or classList.remove():

const element = document.querySelector('#foo')
 
if (element) {
  element.classList.add('active')
  element.classList.remove('hidden')
}

Class names do not include the dot used in CSS selectors. Pass 'active', not '.active'.

Both methods accept multiple class names:

element.classList.add('active', 'highlighted')
element.classList.remove('hidden', 'disabled')

If the classes are in an array, spread it into the method:

const classes = ['active', 'highlighted']
 
element.classList.add(...classes)

Adding an existing class or removing a missing class has no effect.

Toggle a class

toggle() adds a class when it is missing and removes it when it is present. It returns true when the class is present after the call:

const button = document.querySelector('#menu-button')
const menu = document.querySelector('#menu')
 
button?.addEventListener('click', () => {
  const isOpen = menu?.classList.toggle('open') ?? false
 
  button.setAttribute('aria-expanded', String(isOpen))
})

Pass a second boolean argument when the class should reflect a condition. This is clearer than separate add() and remove() branches:

element.classList.toggle('selected', isSelected)

When isSelected is true, the class is added. When it is false, the class is removed.

Check or replace a class

Use contains() to test for a class:

if (element.classList.contains('active')) {
  console.log('The element is active')
}

Use replace() to swap one class for another:

element.classList.replace('loading', 'loaded')

replace() returns false and makes no change if the old class is missing.

Change classes on multiple elements

querySelectorAll() returns a NodeList with a forEach() method. You do not need to convert it to an array:

const accordionItems = document.querySelectorAll('.accordion-item')
 
accordionItems.forEach(item => {
  item.classList.remove('open')
})

Using classList with TypeScript

DOM queries can return null, so check the result before using it. A generic type argument is useful when you also need properties specific to an element:

const button = document.querySelector<HTMLButtonElement>('#submit-button')
 
if (!button) {
  throw new Error('Submit button not found')
}
 
button.addEventListener('click', () => {
  const isLoading = button.classList.toggle('loading')
 
  button.disabled = isLoading
})

Functions that only manipulate classes can accept the broader Element type:

function setSelected(element: Element, selected: boolean): void {
  element.classList.toggle('selected', selected)
}

When to use className

The className property reads or replaces the entire class attribute:

element.className = 'card featured'

This removes every existing class before setting the new value. Use it only when replacing the complete class list is intentional. For individual classes, prefer classList over string concatenation or regular expressions.

See the MDN classList reference for the full API.