Mozilla

Hidden Gems of HTML5: classList

If you are a web developer, you surely must know how handy it is to dynamically change the class attribute on an element. The benefits this technique are quite a few:

  • You leave any changes in the look and feel to the CSS
  • You avoid having to loop lots of elements as you can allow CSS to do that job for you by assigning a class on a parent element
  • You can trigger CSS transitions and avoid having to write your own animation
  • And many more…

The issue with classes is that it is not too simple to work with because of their representation in the DOM. When you read out className you get one string and you need to split it and use regex to find if a class was used and all kind of other annoyances. This is also why it is a very common interview questions for web developers to write a function to deal with classes.

Well, you might not be aware of it, but HTML has a very cool new way to deal with classes called classList. This makes it dead easy to add, remove, toggle and check for classes on an element – natively in your browser. You can play with it at JSFiddle:

JSFiddle demo.

The methods you have are all you really need:

  • element.classList.add('foo') adds the class foo to the element (if it already exists it does nothing)
  • element.classList.remove('foo') removes the class foo from the element
  • element.classList.toggle('foo') alternatively adds and removes the class foo from the element
  • element.classList.contains('foo') returns if the class is applied to the element or not
  • element.classList.toString() returns all the classes as a string (same as reading out className)

The browser support is very good with IE being the party pooper. However, there is a polyfill by Eli Grey available for you to use.

21 comments

Comments are now closed.

  1. Calvein wrote on January 30th, 2012 at 05:23:

    The biggest problem with this API is that you can’t use those methods on more than one class. That’s sad.

    1. Chris Heilmann wrote on January 30th, 2012 at 05:33:

      you mean add(‘foo’,’bar’) or add(['foo','bar']) ? What would be the use case of those?

      1. Calvein wrote on January 30th, 2012 at 05:36:

        I was thinking more about `contains` than `add`.

        1. Greg wrote on January 30th, 2012 at 06:07:

          should it default to OR or AND?

      2. MT wrote on January 30th, 2012 at 06:10:

        Operating on multiple classes at once is heavily used, for example, in jQuery UI.

        For details as for DOMTokenList’s problems with inability to operate on multiple tokens at once, see https://www.w3.org/Bugs/Public/show_bug.cgi?id=13999

      3. mig wrote on January 30th, 2012 at 07:12:

        Using jQuery a lot, i find myself doing $(element).addClass(“foo bar”) or $(element).removeClass(“foo bar”) very often. This is a nice convenience.

  2. Mustafa wrote on January 30th, 2012 at 05:24:

    Thats sweeeet :)

    one thing though, the articles title says html5 but isnt this just javascript?

    1. Chris Heilmann wrote on January 30th, 2012 at 05:34:

      It is part of the living HTML spec – and it is an HTML property. So it is HTML5. A lot of JavaScript is described in the spec.

      1. Mustafa wrote on January 31st, 2012 at 13:48:

        Thanks for clearing that up :)

  3. Joost Elfering wrote on January 30th, 2012 at 05:46:

    This is a nice gem in the new HTML5 spec!

    Support seems to be okay but a fallback is naturally in order. Are there any performance figures for this compared to jQuery type solutions for this problem?

  4. Motyar wrote on January 30th, 2012 at 06:25:

    Good to know, ll create something amazing using this.

  5. MT wrote on January 30th, 2012 at 07:47:

    We probably should have separate methods such as:

    — contains() for AND (would return true if element has all given tokens);

    — containsOne() for OR (would return true if element has any of given tokens).

  6. MT wrote on January 30th, 2012 at 07:49:

    That was reply to Greg’s comment:
    hacks.mozilla.org/2012/01/hidden-gems-of-html5-classlist/comment-page-1/#comment-1328637

  7. Rob wrote on January 30th, 2012 at 07:53:

    This is cool but the class tool I use most in jQuery is toggleClass with the second argument as a boolean.

    1. Chris Heilmann wrote on January 30th, 2012 at 08:42:

      Good for you, but jQuery is not a standard and needs to be loaded separately. Which is not always an option.

  8. louisremi wrote on January 30th, 2012 at 08:22:

    The classList API is very nice indeed, but if you’re searching for a cross browser solution, here’s a 140bytes function: https://gist.github.com/1319121

    the API is:
    c( elem, “has”, name );
    c( elem, “add”, name );
    c( elem, “remove”, name );
    c( elem, “toggle”, name );

  9. Brian Birtles wrote on January 30th, 2012 at 16:38:

    One thing to be aware of is that WebKit’s support for classList doesn’t extend to inline SVG (unlike Firefox and Opera). To work around that I have a modified version of Eli Grey’s shim:
    https://github.com/birtles/parapara/blob/master/editor/js/svgClassList.js

    It also extends support to SVG embedded via (but not yet or ).

  10. Brian Birtles wrote on January 30th, 2012 at 16:40:

    Apparently you can’t use angle brackets in posts here. That last comment should say that the modified classList doesn’t extend support to embed elements or iframe elements yet.

  11. Drew wrote on January 31st, 2012 at 10:35:

    If this native method is faster than jQuery’s current methods, I’d expect they’d probably update the code to use it when available.

  12. Coursework wrote on March 15th, 2012 at 04:33:

    I always use classList whenever build any page of my website in HTML. I built many color schemes in various static web pages by using classList. The methods which you shared, some of them I didn’t know which will now be very helpful for me and other HTML developers.

  13. sam wrote on October 18th, 2012 at 14:41:

    I just wrote a jsperf to test a simple “contains” test and found it to be 50% slower than a simple indexOf() test. This is a shame because indexOf() is usually not the fastest way to search for a string.

    http://jsperf.com/html5-class-list

Comments are closed for this article.