Skip to main content
Dublin Library

The Publishing Project

Programmatically manipulating CSS classes

 

When working with Javascript there will be times when we need to change the CSS we apply to the web pages we're working on.

Javascript provides two methods to manipulate an HTML element's classes: className and classList.

For this post we'll concentrate in classList since it provides methods to manipulate the class attribute and it avoids the string manipulation that you'd have to do when working with className.

classList is a read-only property that returns a live space-separated list of the class attributes of the element that we can manipulate using classList methods

The classList methods are:

add()
Adds one or more tokens to the element's class attribute, skipping duplicates
remove()
Removes the specified token from the list
replace()
Replaces the old token (the first parameter) with the new value (the second parameter)
If the old token doesn't exist, replace() will return false and will not add the second token to the class attribute
toggle()
Cycles through states of the specified attribute
If the attribute exists then toggle() will remove it and return false
If the attribute doesn't exist, toggle() will add it and return true
contains()
Searches the class attribute. Returns true if the class is present and false otherwise

Examples #

I created a Codepen to illustrate how classList works.

The HTML defines the structure of the demo. The box with id of myBox will change based on the buttons we push.

Each button exercises a different method of classList discussed earlier. scan doesn't have a button because we used in the Javascript without producing visible results.

<div class="content-wrapper">
  <div id="myBox" class="box thin">
    <p>content</p>
  </div>

  <div class="button-row">
    <button id="addBtn">Add Class</button>
    <button id="removeBtn">Remove Class</button>
    <button id="replaceBtn">Replace Class</button>
    <button id="toggleBtn">Toggle Class</button>
    <button id="scanBtn">Scan for box Class</button>
  </div>
</div>

The CSS provides all the styling for the demo. Some of these styles like .content-wrapper, .box, and .button-row are structural; they define the look of the app. The others are used in the demo to show changes resulting from using the classList methods.

.content-wrapper {
  margin-block-start: 3rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.box {
  width: 200px;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.button-row {
  margin-block: 2em;
  width: 200px;
  display: flex;
  flex-flow: row wrap;
  gap: 0.75em;
}

button: {
  width: 45px;
}

.thin {
  border: 5px solid black;
}

.thick {
  border: 10px solid black;
}

.hotpink {
  background: hotpink;
  color: white;
}

.blue {
  background: navy;
  color: white;
}

The Javascript code does the bulk of the work since it actually trigger the class changes.

In the first part of the code we capture references to the box and the buttons on the page using querySelector. If you have more than one element that matches the query then querySelector will only return the first ocurrence, if you want to work with all the matching elements use querySelectorAll

const myBox = document.querySelector("#myBox");

const add = document.querySelector("#addBtn");
const remove = document.querySelector("#removeBtn");
const replace = document.querySelector("#replaceBtn");
const toggle = document.querySelector("#toggleBtn");

The next step is to define event listeners for each button we created.

The remove (removeBtn) and replace (replaceBtn) use classList.contains to test if the class or classes we want to remove or replace exists before taking action.

This is particularly important with the classList.replace method since it will throw an error if the class we want to replace doesn't exist. So to avoid errors, making sure you're replacing a class that exists or provide a workaround like what we did here.

addBtn.addEventListener("click", (evt) => {
  myBox.classList.add("hotpink");
});

removeBtn.addEventListener("click", (evt) => {
  if (myBox.classList.contains("hotpink")) {
    myBox.classList.remove("hotpink");
  }
  if (myBox.classList.contains("blue")) {
    myBox.classList.remove("blue");
  }
});

replaceBtn.addEventListener("click", (evt) => {
  if (!myBox.classList.contains("hotpink")) {
    myBox.classList.add("hotpink");
    myBox.classList.replace("hotpink", "blue");
  } else {
    myBox.classList.replace("hotpink", "blue");
  }
});

toggleBtn.addEventListener("click", (evt) => {
  myBox.classList.toggle("thick");
});

The full Codepen is shown below.

Edit on Github