The thing is though, I’m writing about the
Before this nugget of HTML5 came along, working with classes was a royal pain, but what was once a twisty overgrown cowpath with wolves lurking in thickets is now a bright sunlit path fit for rollerskating.
Getting the classList #
classList is a simple matter of
element.classList, like so:
That will log something like
["oh", "my", "giddy", "aunt"]. The output style varies between browsers, but it will be an object containing a list of the classes on the element.
More accurately, it’s an object that stringifies to the value of the class attribute on the element in question. Try it yourself with the console open.
There is no specification for
classList per se (it gets a sentence in the DOM4 spec), but there is for
DOMTokenList, which is
classList‘s type, so look at the
DOMTokenList specification to find out how to work with lists of classes.
The Type of classList #
If you’re looking to confirm the type of
classList, you’ll need to do
element.classList instanceof DOMTokenList, which returns
Doing Things with our List of Classes #
DOMTokenList spec provides a number of methods that can be used on the
add()for adding a class to the list
remove()for removing a class from the list
contains()to check if a class is in the list
toggle()for toggling a class in and out of the list (with a twist)
item()to return the class at a specified position in the list
toString()for turning the list into a string
lengthto return the number of classes in the list
valueto add custom properties and methods to the
It couldn’t be easier to add a class to an element. Just supply the class you want to add as an argument to the
If you view the demo and look at the opening
<p> tag in your favourite inspector before and after pressing the button, you’ll see it change from
<p id="bad-joke" class="oh my giddy aunt"> to
<p id="bad-joke" class="oh my giddy aunt beryl">.
Adding a class to the
<p> is all done with that one line. No need to inject inline styles or anything messy like that.
classList object is:
Removing a class is just as easy.
joke.classList.remove('beryl') brings us back to where we started.
Adding and Removing Multiple Classes #
DOMTokenList spec refers to “tokens”, plural when describing how the
remove() methods should be run.
The add(tokens…) method […] If one of tokens is the empty string […] If one of tokens contains any ASCII whitespace […] For each token in tokens
No browser so far has implemented a native method of adding/removing more than one class at a time, but it’s trivial to extend the
DOMTokenList object prototype with a hand rolled function:
Thanks to David and Kalley for pointing that out in the comments.
Same goes for remove:
A bug was filed in 2011 (against a document that no longer exists) suggesting allowing a space separated list or an array in
The use of the plural “tokens” could be interpreted as allowing an array, but it doesn’t work.
InvalidCharacterError is still specified as the exception to throw if there are any spaces in “tokens”, so that’s definitely not going to work.
If you want to replace an entire
classList with a completely different set of classes, you could use these two functions.
This method returns a Boolean
false when checking for the presence of a class in the list.
In our example:
contains() is useful for checking if a class is in a list before performing an action that depends on its presence (or otherwise):
We can use
contains() to make our previous functions for adding and removing multiple classes better by ensuring they do not try to add duplicate classes on the element or remove classes that don’t exist on it:
For most use cases,
classList.toggle() is very straightforward too. Typically, an action by the program or the user will trigger a function that adds or removes a class depending on whether it’s already in the list.
A simple show/hide is a good example of this:
View a demo of a two-level menu that takes up a little less room in smaller viewports by using
classList.toggle() to enhance sub-menus.
There’s a little twist to
toggle(), though. It can take an optional second parameter,
force is set to
true, the class will be added but not removed. If it’s
false, the opposite will happen — the class will be removed but not added.
Now that sounds a lot like
remove(), but there is a crucial difference:
true when a class is added, and
false when it’s removed —
At the time of writing, only the Blink powered browsers honour the
force parameter, so view the demo with true and the demo with false in Opera 15, Opera for Android, or the latest Chrome to see it working.
Browsers that don’t support
force completely ignore it and merrily toggle the class name on and off without throwing exceptions.
When it’s more widely supported, we can use a slightly leaner syntax for ensuring the presence or absence of a class in the list. Instead of:
we could write:
index counting from zero.
In our example:
classList.item() cannot be used for assignment, so
joke.classList.item(3) = 'uncle' will throw an error.
If you were hoping
classList.item() could assign values to items at specific positions in the list, I’m afraid you’ll be disappointed. There’s no
DOMTokenList method that gives that level of control over the list.
If you ever need the
classList turned into a string use this method.
All the W3C spec says on the subject is that
DOMTokenList objects must stringify to the underlying string. WHATWG leaves it at
The stringifier must return the result of the set serializer for the associated list of tokens.
The only difference between the two is the amount of plain English used.
It takes no parameters when used with
classList and returns all the classes on the element as a space separated string:
classList. In our example using “oh my giddy aunt”, it’s
Simple and obvious, hopefully.
On their own, the
length methods aren’t especially useful. They can, however, be used in conjunction with each other and the rest of the methods of
DOMTokenList to solve some of the problems I mentioned earlier.
And of course we can add methods. Here’s a method that replaces the entire list with a new one using
And here’s a method that inserts a class in any position in the list you want. It uses
toString(), and the
replace() method we just made:
Being realistic, methods like these would probably be better used to extend
DOMTokenList like we did with
removemany(), but if you ever need something specific to a particular
classList you’re working on, you can use
Browser Support and Polyfills #
classList API works in pretty much every up-to-date browser version. Basic support at least has been in since Firefox 3.6, Opera 11.50, Chrome 8, and Safari 5.1.
The big holes are IE9 and earlier and the still widely used Android 2.3 and earlier.
There are at least two polyfills available that can fill these holes.
Eli Grey’s polyfill has wider browser support. It works in IE8, and it provides basic
classList.toggle() support to at least as far back as Android 2.1.
There’s also a polyfill for adding
force support by Егор Халимоненко to browsers that support
classList but not
If you only need a simple feature test you can use:
You can think of the
classList API on two levels. For most uses, it’s a simple way to add, remove, toggle, and check for the presence of single classes in an HTML element. I use it in every project I work on now and very rarely need to stray beyond these basic methods. I can’t think of any use for
toString() as stand-alone methods, so don’t fret about them.
On another level, it’s about objects, it’s about finding powerful ways to manipulate the state of web pages, it’s about separation of concerns, it’s about progressive enhancement.
How far you take it is up to you, but as I said at the start, it’s an easy one to get into and makes what was hard, easy. I encourage you to take what I’ve written here and experiment in your own projects if you’re new to it, and take to the comments to tell me where I could have said it better if you’re already familiar with it.