Introduction
The class attribute in HTML is used to define a class for one or more HTML elements. This way, a lot of elements can belong to the same class of elements and share the same style in the style sheet, so you don't have to write the same style for every element over and over again.
That being said, sometimes you want to change styles dynamically, depending on the user's input. For example, you want to implement day/night mode for your web page, which can effectively be done with changing element's class.
This is a common task for when you want to let the user customize any aspect of your application. In this guide - we'll take a look at how to change the class of an HTML element in JavaScript.
DOM Tree
The DOM or Document Object Model is an interface that creates a tree structure from XML or HTML. The hierarchy of the document's elements is represented through the DOM. A tree is made up of nodes and branches, where elements are nodes and elements' relations are branches. In the DOM Tree, the root node is html - the very first element necessary to start marking up an HTML document:
<!DOCTYPE HTML>
<html>
<head>
<title>Web page title</title>
</head>
<body>
<h1>Some heading</h1>
</body>
</html>
The DOM tree for this page would look like this:
This is a very simple tree, but the same process applies to any arbitrarily complex page. Thanks to the DOM tree, through JavaScript, we can access all of the HTML elements on the page, as well as elements' classes, ids, content and all their attributes. We can even add new elements and remove old ones. We can create events to listen to and respond to them (i.e. change background color when a button is clicked).
Getting the Elements
Now that we know that we can obtain an element from HTML, let's see how to actually do that using JavaScript. To change an element's class, we first have to retrieve it. Depending on the element, we can obtain them through a few different approaches:
getElementsByClassName(class_name)
- returns anHTMLCollection
which contains HTML elements whose class names are equal toclass_name
.getElementById(id_name)
- returns a single HTML element whose id is equal toid_name
.getElementsByTagName(tag_name)
- returns anHTMLCollection
of elements with a tagtag_name
.
We'll be working with this HTML file:
<!DOCTYPE HTML>
<html>
<head>
<title>Web page title</title>
</head>
<body class="page-body">
<h1 class="headings">Some heading</h1>
<h3 class="headings">More of some heading</h3>
<h5 class="headings">Another heading here</h5>
<a href="https://www.google.com" id="link-to-google">Some random link</a>
<ul>
<li>Thing #1</li>
<li>Thing #2</li>
<li>Thing #3</li>
</ul>
</body>
<script src="script.js"></script>
</html>
Getting Elements Using getElementsByClassName()
Let's make the script.js
file that's imported to our page:
$ touch script.js
And within it - we'll locate and retrieve the elements which belong to the "headings" class
:
console.log(document.getElementsByClassName("headings"));
Since there's likely to be more than one element belonging to the same class - this returns an HTMLCollection
:
HTMLCollection(3)
- 0: h1.headings
- 1: h3.headings
- 2: h5.headings
length: 3
An HTMLCollection
is a collection of HTML elements, which offers a variety of methods for selecting them from the collection, such as:
className()
- Returns a string which represents the name of the class; This method can also be used to set an element's class (which is exactly what we need).innerHTML()
- Since HTML elements can be nested in one another, if there are nested elements, this method will return them as HTML.innerText()
- Returns all of the text inside of an element (including nested elements).
There are also a lot of events which we can listen to, such as: onclick
, ondblclick
, onkeydown
, onkeypress
. You can find out more about JavaScript's events in the official documentation.
Getting Elements Using getElementById()
You can snatch elements by their id, via the getElementById()
method:
console.log(document.getElementById("link-to-google"));
Which results in:
<a href="https://www.google.com" id="link-to-google">Some random link</a>
Getting Elements Using getElementsByTagName()
Finally, we can also find elements by their tag, if they don't have a class or id. This returns a collection of HTML elements, because you typically have more than a single one with the same tag.
Now, if we want to get all of the <li>
elements, we can search by the li
tag:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
console.log(document.getElementsByTagName("li"));
Which results in:
HTMLCollection(3) [li, li, li]
- 0: li
- 1: li
- 2: li
The return value is the same as getElementsByClassName
- an HTMLCollection
.
Regardless of the approach used to obtain an element - we can now change its class.
Changing an Element's Class using JavaScript
Changing Element Class with className
Let's create a dummy index.html
page containing some data. We'll allow the user to switch between the "day mode" and "night mode", which changes the color palette used on the webpage. We'll also need a script.js
file imported here, to find and change the elements, as well as a style.css
file that'll contain all of our styling code.
Let's start off with the index.html
:
<!DOCTYPE HTML>
<html>
<head>
<title>Day/night mode</title>
<link rel="stylesheet" href="style.css"/>
</head>
<body class="page-body-day" id="page-body">
<h1 class="main-heading-day" id="main-heading">Some heading</h1>
<p>Dummy text, dummy text, dummy text</p>
<p>Some more dummy text, more dummy text, more dummy text</p>
<button onclick="switchMode()">Switch day/night mode</button>
</body>
<script src="script.js"></script>
</html>
All the elements that will change their appearance when the user clicks on the Switch day/night mode button have their respective ids and are assigned the default element-day
class respectively.
Each element-day
class has a element-night
alternative in the style.css
file:
.page-body-day {
background-color: white;
color: black;
}
.page-body-night {
background-color: #02182B;
color: yellow;
}
.main-heading-day {
color: black;
}
.main-heading-night {
color: yellow;
}
Since we'll be changing the class of our elements, we don't want to search by the class, otherwise, we'll have edge cases. We'll want to search by something of fixed value, which is the id, and then check the className
of that element - changing it to the appropriate class in the process:
function switchMode(){
// Body switching
if(document.getElementById("page-body").className == "page-body-day"){
document.getElementById("page-body").className = "page-body-night";
}else{
document.getElementById("page-body").className = "page-body-day";
}
// Heading switching
if(document.getElementById("main-heading").className == "main-heading-day"){
document.getElementById("main-heading").className = "main-heading-night";
}else{
document.getElementById("main-heading").className = "main-heading-day";
}
}
The className
returns the name of the class of that element. Though, if we assign a new value to it - we can effectively update the class
property of a tag. If the element has an element-day
class, we'll change it to element-night
and vice-versa.
When changing the body's color
property in CSS, we are automatically changing all the elements that don't have the color
attribute defined (in our case it is our <p>
tags). When class switching happens, CSS starts reading newly switched classes and applies styles accordingly.
Though, this approach isn't very modern, and is mainly used to accommodate for the lagging functionality of Internet Explorer 8 and 9.
Changing Element Class with classList
Newer Internet browsers have support for a newer property called classList
. What this property provides is a list of all the classes which are applied to a certain HTML element.
Note: Internet Explorer 8 and 9 do not support classList
.
classList
has a couple of methods that we can leverage:
add(class_name)
- adds a new classclass_name
to the list.remove(class_name)
- removes a classclass_name
from the list.toggle(class_name)
- adds classclass_name
if it is not already added, otherwise removes it.contains(class_name)
- checks whetherclass_name
is in the list of classes applied to the HTML element.
That being said - we can rewrite out script.js
file to use these methods instead:
function switchMode(){
// Body switching
if(document.getElementById("page-body").classList.contains("page-body-day")){
document.getElementById("page-body").classList.remove("page-body-day");
document.getElementById("page-body").classList.add("page-body-night");
} else{
document.getElementById("page-body").classList.remove("page-body-night");
document.getElementById("page-body").classList.add("page-body-day");
}
// Heading switching
if(document.getElementById("main-heading").classList.contains("main-heading-day")){
document.getElementById("main-heading").classList.remove("main-heading-day");
document.getElementById("main-heading").classList.add("main-heading-night");
} else{
document.getElementById("main-heading").classList.remove("main-heading-night");
document.getElementById("main-heading").classList.add("main-heading-day");
}
}
This approach is supported in HTML5 and in modern browsers and this way you can manipulate classes in a similar fashion to jQuery - a JavaScript library widely used to manipulate HTML elements, events, etc.
Through classList
, you can skip including an external library which reduces the PLT (Page Load Time) which has recently become an important Web Vital signal for SEO-grading.
Conclusion
JavaScript gained mass-adoption because of how simple the DOM makes it to manipulate basically everything on your web page, amongst other things.
In this tutorial, we took a look at how to change an element's class in JavaScript.