Skip to main content
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Jason Dean
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Jason Dean

Using Element.classList To Manipulate CSS Classes On The DOM

By
Published in

Over the weekend, I finished the Learn Node video course by Wes Bos. It was a great course; but, one of the things that I love about watching video tutorials, like Learn Node, is that you pick up lots of little tid-bits that are only peripherally related to the topic at hand. For example, in one of the videos, I saw Wes adding and removing CSS classes using a .classList DOM (Document Object Model) property. Historically, I've used the .className DOM property to try and manipulate class names; but, using .classList looks so much easier. As such, I wanted to take a quick look at how it works.

To be honest, CSS manipulation is one of those things that I rarely do by hand anymore. Normally, in an application, I use Angular or ReactJS to apply class names based on application state. But, I think there's a lot of value in understanding how JavaScript and the Document Object Model can be used outside of a framework. After all, a framework only gets you started - it's core JavaScript and DOM insights that get you to the finish line.

With that said, the .classList Element property presents a token-list (ie, a space-delimited String) of the classes being applied to the Element. But, unlike the traditional .className property, the .classList property provides convenience methods for accessing and manipulating the individual classes in the .classList:

  • .add( String )
  • .remove( String )
  • .contains( String )
  • .item( Number )

NOTE: There are other methods on the .classList property that are less widely supported, like .toggle().

To see this in action, I've put together a small demo in which the user can add and remove classes to and and from a target element:

<!doctype html>
<html>
<head>
	<meta charset="utf-8" />

	<title>
		Using Element.classList To Manipulate CSS Classes On The DOM
	</title>

	<style type="text/css">

		p, ul {
			font-size: 20px ;
		}

		p {
			border: 3px solid #DADADA ;
			border-radius: 5px 5px 5px 5px ;
			padding: 20px 20px 20px 20px ;
		}

		a {
			color: red ;
			cursor: pointer ;
			text-decoration: underline ;
			user-select: none ;
				-moz-user-select: none ;
				-webkit-user-select: none ;
		}

		.one {
			color: red ;
		}

		.two {
			font-weight: bold ;
		}

		.three {
			font-style: italic ;
		}

	</style>
</head>
<body>

	<h1>
		Using Element.classList To Manipulate CSS Classes On The DOM
	</h1>

	<p class="line">
		I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time... like tears in rain... Time to die.
	</p>

	<ul>
		<li>
			Class .one &mdash;
			<a data-class="one" class="add">Add</a> ,
			<a data-class="one" class="remove">Remove</a>
		</li>
		<li>
			Class .two &mdash;
			<a data-class="two" class="add">Add</a> ,
			<a data-class="two" class="remove">Remove</a>
		</li>
		<li>
			Class .three &mdash;
			<a data-class="three" class="add">Add</a> ,
			<a data-class="three" class="remove">Remove</a>
		</li>
	</ul>


	<script type="text/javascript">

		var line = document.querySelector( "p.line" );

		// Wire-up event-delegation for our add / remove click handlers.
		document.body.addEventListener(
			"click",
			function handleClick( event ) {

				var clickTarget = event.target;

				// In the following logic, we're using the classList to implement the
				// event-delegation (checking for "add" and "remove" classes on the
				// click-target). Then, we're also using the classList to add and remove
				// the relevant class to and from the demo line.
				// --
				// CAUTION: I'm using "dataset" instead of getAttribute() to access the
				// data-* attributes on the click-target. This is only available in IE 11+.
				if ( clickTarget.classList.contains( "add" ) ) {

					line.classList.add( clickTarget.dataset.class );

				} else if ( clickTarget.classList.contains( "remove" ) ) {

					line.classList.remove( clickTarget.dataset.class );

				} else {

					return;

				}

				// Now that the event-delegation action has been applied, let's look at
				// what classes have been applied to the demo line.
				console.log( "CLASSES:", line.classList.value );

			}
		);

	</script>

</body>
</html>

As you can see, the links in the demo add or remove the classes "one", "two", and "three". In the logic for the event-delegation-based click-handler, I'm using the .classList property in several ways:

  • I'm checking to see if the click-target is one of the action links.
  • I'm adding or removing the relevant class.
  • I'm logging the resultant class list.

As you can see, using the .add(), .remove(), and .contains() convenience classes is much easier than trying to perform manual string manipulation on .className. And, when we run this demo and toggle a few classes, we get the following output:

DOM Element .classList property helps manipulate CSS class names.

As you can see, by using the .classList convenience methods - .add() and .remove() - we were able to add and remove individual classes without having to do any string manipulation.

Like I said above, with a JavaScript framework, there's probably not much need to do explicit class manipulation on the Document Object Model. But, it's helpful to know that this .classList functionality exists; and, how easy it is to leverage.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel