Manipulating a list of CSS classes
Adding a class
Modern browsers provide a classList
object to ease manipulation of the element’s class attribute. Older browsers require direct manipulation of the element’s className
property.
A simple method to add a class to an element is to append it to the end of the className
property. This will not prevent duplicate class names, and spaces must be included between class names.
document.getElementById("link1").className += " foo";
document.getElementById("link2").className += " foo bar";
For multiple elements, you’ll need to add the class names inside of a loop
var els = document.getElementsByClassName("foo"),
indx = els.length;
while (indx--) {
els[indx].className += " bar baz";
}
A single class name may be added as a string. To add multiple class names, use ES6’s spread operator:
document.querySelector("#link1").classList.add("foo");
document.querySelector("#link2").classList.add(...['foo', 'bar']);
For multiple elements, you’ll need to add the class names inside of a loop
document.querySelectorAll(".foo").forEach(el => {
el.classList.add(...['bar', 'baz']);
});
Removing a class
Modern browsers provide a classList
object to ease manipulation of the element’s class attribute. Older browsers require direct manipulation of the element’s className
property.
* Note class names are not stored in the element’s property in any particular order
Removing one class from an element requires a bit of manipulation of the className
property.
var toRemove = "bar",
el = document.getElementById("link1");
el.className = el.className.replace(new RegExp("\\b" + toRemove + "\\b", "g"), "").trim();
Removing multiple class names would require a loop. The remaining examples will use a function to isolate the work
function removeClass(el, name) {
name = name.split(/\s+/);
var index = name.length,
classes = el.className;
while (index--) {
classes = classes.replace(new RegExp("\\b" + name[index] + "\\b", "g"), "").trim();
}
el.className = classes;
}
var el = document.getElementById("link1");
removeClass(el, "bar baz");
Multiple elements with multiple class names to remove would require two loops
function removeClass(els, name) {
name = name.split(/\s+/);
var regex, len,
index = name.length;
while (index--) {
regex = new RegExp("\\b" + name[index] + "\\b", "g");
len = els.length;
while (len--) {
els[len].className = els[len].className.replace(regex, "").trim();
}
}
}
var els = document.getElementsByTagName("a");
removeClass(els, "bar baz");
A single class name may be removed as a string. To remove multiple class names, use ES6’s spread operator:
document.querySelector("#link1").classList.remove("foo");
document.querySelector("#link2").classList.remove(...['foo', 'bar']);
For multiple elements, you’ll need to remove the class names inside of a loop
document.querySelectorAll(".foo").forEach(el => {
el.classList.remove(...['bar', 'baz']);
});
Testing for a class
Modern browsers provide a classList
object to ease manipulation of the element’s class attribute. Older browsers require direct manipulation of the element’s className
property.
* Note class names are not stored in the element’s property in any particular order
Testing if an element contains a class requires a bit of manipulation of the className
property. This example is using an array method to test for the class.
function hasClass(el, name) {
var classes = (el && el.className || "").split(/\s+/);
return classes.indexOf(name) > -1;
}
var el = document.getElementById("link1");
console.log(hasClass(el, "foo"));
Testing for multiple class names would require a loop.
function hasClass(el, name) {
name = name.split(/[\s.]+/);
var hasClass = true,
classes = (el && el.className || "").split(/\s+/),
index = name.length;
while (index--) {
hasClass = hasClass && classes.indexOf(name[index]) > -1;
}
return hasClass;
}
var el = document.getElementById("link1");
console.log(hasClass(el, "foo"));
Instead of using .indexOf()
, you may also consider using a regular expression.
function hasClass(el, name) {
return new RegExp("\\b" + name+ "\\b").test(el.className);
}
var el = document.getElementById("link1");
console.log(hasClass(el, "foo"));
Testing for a single class name is done as follows:
var hasClass = document.querySelector("#link1").classList.contains("foo");
For multiple class names, it is easier to use matches
. Note the use of the class selector; The selector can be any valid string selector (id, attribute, pseudo-classes, etc).
var hasClass = document.querySelector("#link1").matches('.foo.bar');
var hasClass = document.querySelector("#link2").matches('a.bar[href]');