By Nathan Smith


2008-10-12 20:06:43 8 Comments

How can I change a class of an HTML element in response to an onclick event using JavaScript?

30 comments

@tfont 2019-02-22 10:22:35

Lots of answers, lots of good answers.

TL;DR :

document.getElementById('id').className = 'class'

OR

document.getElementById('id').classList.add('class');
document.getElementById('id').classList.remove('class');

That's it.

And, if you really want to know the why and educate yourself then I suggest reading Peter Boughton's answer, it's perfect.

Note:
This is possible with (document or event):

  • getElementById()
  • getElementsByClassName()
  • querySelector()
  • querySelectorAll()

@donatso 2019-09-04 15:32:07

function classed(el, class_name, add_class) {
  const re = new RegExp("(?:^|\\s)" + class_name + "(?!\\S)", "g");
  if (add_class && !el.className.match(re)) el.className += " " + class_name
  else if (!add_class) el.className = el.className.replace(re, '');
}

using the accepted answer above here is a simple cross-browser function to add and remove class

add class:

classed(document.getElementById("denis"), "active", true)

remove class:

classed(document.getElementById("denis"), "active", false)

@Farhad 2019-08-22 18:28:29


THE OPTIONS.

Here is a little style vs. classList examples to get you to see what are the options you have available and how to use classList to do what you want.

style vs. classList

The difference between style and classList is that with style you're adding to the style properties of the element, but classList is kinda controlling the class(es) of the element (add, remove, toggle, contain), I will show you how to use the add and remove method since those are the popular ones.


Style Example

If you want to add margin-top property into an element, you would do in such:

// Get the Element
const el = document.querySelector('#element');

// Add CSS property 
el.style.margintop = "0px"
el.style.margintop = "25px" // This would add a 25px to the top of the element.

classList Example

Let say we have a <div class="class-a class-b">, in this case, we have 2 classes added to our div element already, class-a and class-b, and we want to control what classes remove and what class to add. This is where classList becomes handy.

Remove class-b

// Get the Element
const el = document.querySelector('#element');

// Remove class-b style from the element
el.classList.remove("class-b")

Add class-c

// Get the Element
const el = document.querySelector('#element');

// Add class-b style from the element
el.classList.add("class-c")


@Andrew Orsich 2011-05-28 07:32:53

In one of my old projects that did not use jQuery, I built the following functions for adding, removing and checking if element has class:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
    if (!hasClass(ele, cls)) ele.className += " " + cls;
}
function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

So, for example, if I want onclick to add some class to the button I can use this:

<script type="text/javascript">
    function changeClass(btn, cls) {
        if(!hasClass(btn, cls)) {
            addClass(btn, cls);
        }
    }
</script>
...
<button onclick="changeClass(this, "someClass")">My Button</button>

By now for sure it would just be better to use jQuery.

@Mike 2013-07-24 05:16:09

This is great for when your client doesn't let you use jQuery. (Cause you end up almost building your own library.)

@kfrncs 2013-11-18 05:04:37

@Mike If the client doesn't let you use jQuery, could you not just go through and rebuild only the features you needed into your own library?

@Mike 2013-11-18 19:17:16

@kfrncs Because I don't generally need that large of a framework. For the project I was thinking of, the only functions I needed were the 3 classname(has,add,remove) functions and the cookie(has, add, remove) functions. Everything else was either custom, or natively well supported. So everything together was then only 150 lines before minifying, including comments.

@LessQuesar 2015-12-16 09:25:22

Dude, its 4am and thank you much. Vanilla JS is what we're use on my project and this was a life saver.

@WebWanderer 2017-10-17 21:36:23

This is my favorite solution for this. I use it everywhere. I believe it is the most elegant way to achieve adding and removing classes when your project does not already have another way of doing it.

@WebWanderer 2017-10-17 21:45:05

It should be noted that after using addClass and removeClass on the same element, the element's className will contain an additional space. The className modifying line of removeClass should be updated to ele.className = ele.className.replace(reg, ' ').trim().replace(/\s{2,}/g, ' ');. This removes trailing whitespace left over and collapses multiple whitespaces into a single space in the className.

@Kamil Kiełczewski 2019-04-14 10:51:42

try

function change(el) { el.className='second' }
.first { width: 50px; height: 50px; background: blue }
.second { width: 150px; height: 150px; background: red; transition: all 0.3s ease-in }
<button  onclick="change(box)">Click me</button>
<div id="box" class="first"></div>

@Danish Khan 2019-02-06 14:02:57

Yes there is many ways to do this. In ES6 syntax we can achieve easily. Use this code toggle add and remove class.

const tabs=document.querySelectorAll('.menu li');

for(let tab of tabs){
  
  tab.onclick=function(){
    
  let activetab=document.querySelectorAll('li.active');
    
  activetab[0].classList.remove('active')
  
    tab.classList.add('active'); 
  }
  
}
body {
    padding:20px;
    font-family:sans-serif;    
}

ul {
    margin:20px 0;
    list-style:none;
}

li {
    background:#dfdfdf;
    padding:10px;
    margin:6px 0;
    cursor:pointer;
}

li.active {
    background:#2794c7;
    font-weight:bold;
    color:#ffffff;
}
<i>Please click an item:</i>

<ul class="menu">
  <li class="active"><span>Three</span></li>
  <li><span>Two</span></li>
  <li><span>One</span></li>
</ul>

@Willem van der Veen 2018-09-21 09:23:12

classList DOM API:

A very convenient manner of adding and removing classes is the classList DOM API. This API allows us to select all classes of a specific DOM element in order to modify the list using javascript. For example:

const el = document.getElementById("main");
console.log(el.classList);
<div class="content wrapper animated" id="main"></div>

We can observe in the log that we are getting back an object with not only the classes of the element, but also many auxiliary methods and properties. This object inherits from the interface DOMTokenList, an interface which is used in the DOM to represent a set of space separated tokens (like classes).

Example:

const el = document.getElementById('container');


function addClass () {
   el.classList.add('newclass');
}


function replaceClass () {
     el.classList.replace('foo', 'newFoo');
}


function removeClass () {
       el.classList.remove('bar');
}
button{
  margin: 20px;
}

.foo{
  color: red;
}

.newFoo {
  color: blue;
}

.bar{
  background-color:powderblue;
}

.newclass{
  border: 2px solid green;
}
<div class="foo bar" id="container">
  "Sed ut perspiciatis unde omnis 
  iste natus error sit voluptatem accusantium doloremque laudantium, 
  totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et 
  quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam 
  voluptatem quia voluptas 
 </div>
  
<button onclick="addClass()">AddClass</button>
  
<button onclick="replaceClass()">ReplaceClass</button>
  
<button onclick="removeClass()">removeClass</button>
  

@Peter Boughton 2008-10-12 20:45:36

Modern HTML5 Techniques for changing classes

Modern browsers have added classList which provides methods to make it easier to manipulate classes without needing a library:

document.getElementById("MyElement").classList.add('MyClass');

document.getElementById("MyElement").classList.remove('MyClass');

if ( document.getElementById("MyElement").classList.contains('MyClass') )

document.getElementById("MyElement").classList.toggle('MyClass');

Unfortunately, these do not work in Internet Explorer prior to v10, though there is a shim to add support for it to IE8 and IE9, available from this page. It is, though, getting more and more supported.

Simple cross-browser solution

The standard JavaScript way to select an element is using document.getElementById("Id"), which is what the following examples use - you can of course obtain elements in other ways, and in the right situation may simply use this instead - however, going into detail on this is beyond the scope of the answer.

To change all classes for an element:

To replace all existing classes with one or more new classes, set the className attribute:

document.getElementById("MyElement").className = "MyClass";

(You can use a space-delimited list to apply multiple classes.)

To add an additional class to an element:

To add a class to an element, without removing/affecting existing values, append a space and the new classname, like so:

document.getElementById("MyElement").className += " MyClass";

To remove a class from an element:

To remove a single class to an element, without affecting other potential classes, a simple regex replace is required:

document.getElementById("MyElement").className =
   document.getElementById("MyElement").className.replace
      ( /(?:^|\s)MyClass(?!\S)/g , '' )
/* Code wrapped for readability - above is all one statement */

An explanation of this regex is as follows:

(?:^|\s) # Match the start of the string, or any single whitespace character

MyClass  # The literal text for the classname to remove

(?!\S)   # Negative lookahead to verify the above is the whole classname
         # Ensures there is no non-space character following
         # (i.e. must be end of string or a space)

The g flag tells the replace to repeat as required, in case the class name has been added multiple times.

To check if a class is already applied to an element:

The same regex used above for removing a class can also be used as a check as to whether a particular class exists:

if ( document.getElementById("MyElement").className.match(/(?:^|\s)MyClass(?!\S)/) )


Assigning these actions to onclick events:

Whilst it is possible to write JavaScript directly inside the HTML event attributes (such as onclick="this.className+=' MyClass'") this is not recommended behaviour. Especially on larger applications, more maintainable code is achieved by separating HTML markup from JavaScript interaction logic.

The first step to achieving this is by creating a function, and calling the function in the onclick attribute, for example:

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }
</script>
...
<button onclick="changeClass()">My Button</button>

(It is not required to have this code in script tags, this is simply for brevity of example, and including the JavaScript in a distinct file may be more appropriate.)

The second step is to move the onclick event out of the HTML and into JavaScript, for example using addEventListener

<script type="text/javascript">
    function changeClass(){
        // Code examples from above
    }

    window.onload = function(){
        document.getElementById("MyElement").addEventListener( 'click', changeClass);
    }
</script>
...
<button id="MyElement">My Button</button>

(Note that the window.onload part is required so that the contents of that function are executed after the HTML has finished loading - without this, the MyElement might not exist when the JavaScript code is called, so that line would fail.)


JavaScript Frameworks and Libraries

The above code is all in standard JavaScript, however it is common practise to use either a framework or a library to simplify common tasks, as well as benefit from fixed bugs and edge cases that you might not think of when writing your code.

Whilst some people consider it overkill to add a ~50 KB framework for simply changing a class, if you are doing any substantial amount of JavaScript work, or anything that might have unusual cross-browser behaviour, it is well worth considering.

(Very roughly, a library is a set of tools designed for a specific task, whilst a framework generally contains multiple libraries and performs a complete set of duties.)

The examples above have been reproduced below using jQuery, probably the most commonly used JavaScript library (though there are others worth investigating too).

(Note that $ here is the jQuery object.)

Changing Classes with jQuery:

$('#MyElement').addClass('MyClass');

$('#MyElement').removeClass('MyClass');

if ( $('#MyElement').hasClass('MyClass') )

In addition, jQuery provides a shortcut for adding a class if it doesn't apply, or removing a class that does:

$('#MyElement').toggleClass('MyClass');


Assigning a function to a click event with jQuery:

$('#MyElement').click(changeClass);

or, without needing an id:

$(':button:contains(My Button)').click(changeClass);


@mattstuehler 2011-05-15 15:32:18

Great answer Peter. One question... why is it better to do with with JQuery than Javascript? JQuery is great, but if this is all you need to do - what justifies including the entire JQuery libray instead of a few lines of JavaScript?

@Barry 2011-05-24 16:46:30

@mattstuehler 1) the phrase "better yet x" often means "better yet (you can) x". 2) To get to the heart of the matter, jQuery is designed to aid in accessing/manipulating the DOM, and very often if you need to do this sort of thing once you have to do it all over the place.

@didxga 2011-07-13 07:07:03

Be ware of that in case of Add Class Name there MUSt be White Space in front of the Class Name you want to add.

@Gabor Magyar 2011-07-27 19:22:45

if you add a class does the previous class get removed, or you have to do that manually?

@Micharch54 2011-08-03 19:15:56

Previous classes will stay. You'll have to remove other classes manually if you want to do that.

@Web_Designer 2011-09-13 16:28:47

One bug with this solution: When you click on your button multiple times, it will add the Class of " MyClass" to the element multiple times, rather than checking to see if it already exists. Thus you could end up with an HTML class attribute looking something like this: class="button MyClass MyClass MyClass"

@Peter Boughton 2011-09-14 00:14:31

I guess the solution to that would be: if ( ! document.getElementById("MyElement").className.match(/(?:^|\‌​s)MyClass(?!\S)/) ) or, with jQuery: if ( ! $j('#MyElement').hasClass('MyClass') ) (although I suspect addClass wont add duplicates?)

@jinglesthula 2011-09-15 05:26:09

If you're trying to remove a class 'myClass' and you have a class 'prefix-myClass' the regex you gave above for removing a class will leave you with 'prefix-' in your className :O

@Peter Boughton 2011-09-15 17:09:51

Wow, three years and 183 upvotes and nobody spotted that until now. Thanks jinglesthula, I've corrected the regex so it wont incorrectly remove parts of class names. // I guess this is a good example of why a Framework (like jQuery) is worth using - bugs like this are caught and fixed sooner, and don't require changes to normal code.

@Peter Boughton 2011-09-15 17:24:12

I've done some minor edits to improve the answer - hopefully people agree they are improvements? If there's anything else I've missed let me know (or just edit the answer yourself).

@Paul 2011-12-21 09:38:09

@PeterBoughton Not sure if you think this is an improvement, but I like: (' '+document.getElementById("MyElement").className+' ').replace( ' '+MyClass+' ' , '' )

@Cris Stringfellow 2012-06-04 10:40:08

@PaulP.R.O. you are collapsing the surrounding spaces and regex to a null, which will concatenate the surrounding class name strings (if any) together. I think elem.className = elem.className.replace( ' ' + classname + ' ' , ' ' ) is what we want. Thanks!

@Christophe 2012-08-15 00:06:16

I use similar methods, but with a g (general) regex. the reason is exactly the issue described by @Web_Designer above: if the user clicks several times, you end up with multiple instances of the same class, and all instances must be removed to remove the class.

@b1nary.atr0phy 2012-10-03 01:01:19

Importing an entire library to accomplish one, simple task is precisely why there is so much overhead drifting around the internet. So I disagree that resorting to JQuery is the "better" solution.

@Peter Boughton 2012-12-12 18:24:01

I have just made substantial additions to this answer - the bulk is the same, but I would appreciate feedback on if there's any mistakes or places for further improvement.

@Sprockincat 2013-01-30 16:44:52

When creating the regex with a variable for the class name I had to look up the syntax: var regExp = new RegExp('(?:^|\\s)' + classToAddOrRemove + '(?!\\S)', 'g');

@brunoais 2013-04-08 07:23:56

One important detail missing here is the difference between framework and library. jQuery is a library, not a framework. Just for the safe of the example, a framework would be angularJs, for example.

@DrJonOsterman 2013-08-02 21:23:46

(You can specify a space-delimited list of elements.) You must mean a list of classes to assign, not elements to select.

@Peter Flynn 2014-01-06 10:13:56

Really excellent answer that fails completely to answer the OP's question: how do you change the value of an existing class?

@Peter Boughton 2014-01-06 16:37:40

If it doesn't answer the OP's question, why did they mark it as the solution? Your question appears to be a different one (possibly you want to change the CSS properties/declarations linked to a class name? not sure if browsers allow that) - why not clarify what you're after in a new question which explains precisely what you want / are trying to achieve?

@ZaLiTHkA 2015-01-22 09:26:33

With regards to the "To add an additional class to an element" point (2nd in list), I find it's best to grab the current el.className, string concat with " class-to-add", and finally call a .trim() on the string before updating the target element. That said, I don't think CSS really cares about the \s, an element's individual classes are determined by a space-separated list anyway.

@Duncan 2015-03-06 19:04:04

heh: var a=[];e.className=((a=e.className.split(" ")).splice(a.indexOf(oldClass),1,newClass)&&a).join(" ").trim(); :D

@Marcel Burkhard 2015-06-02 13:04:06

Can you please rearrange things? In my opinion the classList with shim for browser support should be at the top.

@Nick Humphrey 2015-07-29 08:53:02

would b cool if smth like this worked too, to remove a class name: document.getElementById("MyElement").className -= " MyClass";

@shady sherif 2015-10-05 14:15:03

so the answer simply is $('#MyElement').toggleClass('MyClass'); thanks, It works for me

@Anthony Rutledge 2015-11-07 09:57:03

Hello there. I was wondering what you would say about using word boundaries instead of (?:\s) at the beginning and (?!\S) near the end of your regular expression. Comments? document.getElementById("MyElement").className.replace( /\bMyClass\b/g , '' ). I never seem to have reason to use many of the regular expression short cuts, but this seems (seems) like it could work too. Although, \b has limits on what it considers to be a word character, and you never know what someone might use as a class name.

@Peter Boughton 2015-11-07 14:23:07

\b matches next to hyphens.

@thdoan 2015-11-24 08:48:34

There are faster methods than removing class using RegExp, especially if you're going to turn it into a polyfill. See jsperf.com/removeclass-methods

@Trisped 2016-03-21 18:38:58

The code in the To remove a class from an element: and To check if a class is already applied to an element: sections are missing ; from the end of the line. Is there a reason for this? It would also be nice if there was a note in To remove a class from an element: indicating what happens to spaces. Otherwise, this is a very good answer.

@Andreas Dyballa 2016-05-24 12:18:44

I would prefer (^start(\s+start)*\s*)|((?:\s+)start(?!\S+)) to remove the word start from a whitespace-separeted list.

@Zymotik 2016-06-02 13:59:02

Angular: angular.element(document.getElementById("MyElement")).remove‌​Class("class-name"); angular.element(document.getElementById("MyElement")).addCla‌​ss("class-name")

@pankaj 2016-06-25 14:13:44

Hi this is very nice answer. I want change class on some condition on loading html not click event on button. please refer to this question: stackoverflow.com/questions/38028756/…

@rosell.dk 2016-10-17 20:42:04

Your method for removing a class almost takes care of removing extra spaces that may appear after removing items. But it can happen that the result will start with a leading space. If you add a .trim(), your method for removing a class will not contain any extra spaces.

@rosell.dk 2016-10-17 20:45:06

Also, you can safely remove the "?:" in the beginning of the RegEx, such that it reads: new RegExp​("​(\\s|^​)"+className+"​(?!\\S​)","g"​)

@rosell.dk 2016-10-17 20:48:06

I have created an extensive test of alternatives for removing a class name. Your solution is in the test. The test is available here

@TankorSmash 2017-03-01 17:32:47

@Zymotik you may want to add another separate answer instead of editing someone else's answer. It's a helpful snippet but it should be it's own answer.

@Fahmi 2017-03-16 10:20:23

@Kevin Fegan 2018-10-12 19:27:37

@PoornaSenaniGamage - Your edit says the reason was "improved formatting", I wonder how you could consider it an "improvement"? It was fine before your edit, and well, it's just "fine" after your edit. You just replaced one standard code formatting method that is preferred (well, at least chosen) by the original author, with another standard code formatting method that you happen to prefer. That your edit was approved is a mystery to me, as it seems to me to be an inappropriate edit. Agreed that this is not an extremely significant issue. Someone else, please let me know if I'm out of line.

@JGallardo 2019-10-17 12:25:30

Excellent answer, too bad you left out an example for "(You can use a space-delimited list to apply multiple classes.)" because that would have saved so much time.

@Alireza 2017-05-29 13:29:53

OK, I think in this case you should use jQuery or write your own Methods in pure javascript, my preference is adding my own methods rather than injecting all jQuery to my application if I don't need that for other reasons.

I'd like to do something like below as methods to my javascript framework to add few functionalities which handle adding classes, deleting classes, etc similar to jQuery, this is fully supported in IE9+, also my code is written in ES6, so you need to make sure your browser support it or you using something like babel, otherwise need to use ES5 syntax in your code, also in this way, we finding element via ID, which means the element needs to have an ID to be selected:

//simple javascript utils for class management in ES6
var classUtil = {

  addClass: (id, cl) => {
    document.getElementById(id).classList.add(cl);
  },

  removeClass: (id, cl) => {
    document.getElementById(id).classList.remove(cl);
  },

  hasClass: (id, cl) => {
    return document.getElementById(id).classList.contains(cl);
  },

  toggleClass: (id, cl) => {
    document.getElementById(id).classList.toggle(cl);
  }

}

and you can simply call use them as below, imagine your element has id of 'id' and class of 'class', make sure you pass them as a string, you can use the util as below:

classUtil.addClass('myId', 'myClass');
classUtil.removeClass('myId', 'myClass');
classUtil.hasClass('myId', 'myClass');
classUtil.toggleClass('myId', 'myClass');

@kofifus 2015-10-28 07:00:21

Here's a toggleClass to toggle/add/remove a class on an element:

// If newState is provided add/remove theClass accordingly, otherwise toggle theClass
function toggleClass(elem, theClass, newState) {
    var matchRegExp = new RegExp('(?:^|\\s)' + theClass + '(?!\\S)', 'g');
    var add=(arguments.length>2 ? newState : (elem.className.match(matchRegExp) == null));

    elem.className=elem.className.replace(matchRegExp, ''); // clear all
    if (add) elem.className += ' ' + theClass;
}

see jsfiddle

also see my answer here for creating a new class dynamically

@Ron Royston 2017-04-21 02:50:51

just say myElement.classList="new-class" unless you need to maintain other existing classes in which case you can use the classList.add, .remove methods.

var doc = document;
var divOne = doc.getElementById("one");
var goButton = doc.getElementById("go");

goButton.addEventListener("click", function() {
  divOne.classList="blue";
});
div{
  min-height:48px;
  min-width:48px;
}
.bordered{
  border: 1px solid black;
}
.green{
  background:green;
}
.blue{
  background: blue;
}
<button id="go">Change Class</button>

<div id="one" class="bordered green">

</div>

@Sajid 2016-01-05 18:49:21

Working JavaScript code:

<div id="div_add" class="div_add">Add class from Javascript</div>
<div id="div_replace" class="div_replace">Replace class from Javascript</div>
<div id="div_remove" class="div_remove">Remove class from Javascript</div>
<button onClick="div_add_class();">Add class from Javascript</button>
<button onClick="div_replace_class();">Replace class from Javascript</button>
<button onClick="div_remove_class();">Remove class from Javascript</button>
<script type="text/javascript">
    function div_add_class()
    {
        document.getElementById("div_add").className += " div_added";
    }
    function div_replace_class()
    {
        document.getElementById("div_replace").className = "div_replaced";
    }
    function div_remove_class()
    {
        document.getElementById("div_remove").className = "";
    }
</script>

You can download a working code from this link.

@gcampbell 2016-06-04 15:09:18

This will break elements with more than one class.

@Alex Robinson 2012-05-02 04:59:17

A couple of minor notes and tweaks on the previous regexes:

You'll want to do it globally in case the class list has the class name more than once. And, you'll probably want to strip spaces from the ends of the class list and convert multiple spaces to one space to keep from getting runs of spaces. None of these things should be a problem if the only code dinking with the class names uses the regex below and removes a name before adding it. But. Well, who knows who might be dinking with the class name list.

This regex is case insensitive so that bugs in class names may show up before the code is used on a browser that doesn't care about case in class names.

var s = "testing   one   four  one  two";
var cls = "one";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "test";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "testing";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");
var cls = "tWo";
var rg          = new RegExp("(^|\\s+)" + cls + "(\\s+|$)", 'ig');
alert("[" + s.replace(rg, ' ') + "]");

@Eugene Tiurin 2015-11-04 17:57:07

Change an element's class in vanilla JavaScript with IE6 support

You may try to use node attributes property to keep compatibility with old browsers even IE6:

function getClassNode(element) {
  for (var i = element.attributes.length; i--;)
    if (element.attributes[i].nodeName === 'class')
      return element.attributes[i];
}

function removeClass(classNode, className) {
  var index, classList = classNode.value.split(' ');
  if ((index = classList.indexOf(className)) > -1) {
    classList.splice(index, 1);
    classNode.value = classList.join(' ');
  }
}

function hasClass(classNode, className) {
  return classNode.value.indexOf(className) > -1;
}

function addClass(classNode, className) {
  if (!hasClass(classNode, className))
    classNode.value += ' ' + className;
}

document.getElementById('message').addEventListener('click', function() {
  var classNode = getClassNode(this);
  var className = hasClass(classNode, 'red') && 'blue' || 'red';

  removeClass(classNode, 'red');
  removeClass(classNode, 'blue');

  addClass(classNode, className);
})
.red {
  color: red;
}
.red:before {
  content: 'I am red! ';
}
.red:after {
  content: ' again';
}
.blue {
  color: blue;
}
.blue:before {
  content: 'I am blue! '
}
<span id="message" class="">Click me</span>

@StackSlave 2015-03-20 02:35:01

Just thought I'd throw this in:

function inArray(val, ary){
  for(var i=0,l=ary.length; i<l; i++){
    if(ary[i] === val){
      return true;
    }
  }
  return false;
}
function removeClassName(classNameS, fromElement){
  var x = classNameS.split(/\s/), s = fromElement.className.split(/\s/), r = [];
  for(var i=0,l=s.length; i<l; i++){
    if(!iA(s[i], x))r.push(s[i]);
  }
  fromElement.className = r.join(' ');
}
function addClassName(classNameS, toElement){
  var s = toElement.className.split(/\s/);
  s.push(c); toElement.className = s.join(' ');
}

@Travis J 2012-01-05 19:14:01

Wow, surprised there are so many overkill answers here...

<div class="firstClass" onclick="this.className='secondClass'">

@Lloyd 2012-01-24 10:27:38

yes, but unobtrusive javascript is better practice..

@Gabe 2012-04-13 14:50:41

I would say unobtrusive javascript is terrible practice for writing example code...

@thomasrutter 2015-03-29 23:36:33

I would disagree, because I think example code should set a good example.

@Anthony Rutledge 2015-10-31 04:01:55

A good example should instruct and spark the imagination at the same time. It should not replace thought, but inspire it.

@gcampbell 2016-06-04 15:04:43

The other answers aren't overkill, they also keep existing classes on the element.

@uttamcafedeweb 2014-04-06 06:10:14

Here is simple jQuery code to do that.

$(".class1").click(function(argument) {
    $(".parentclass").removeClass("classtoremove");
    setTimeout(function (argument) {
        $(".parentclass").addClass("classtoadd");
    }, 100);
});

Here,

  • Class1 is a listener for an event.
  • The parent class is the class which hosts the class you want to change
  • Classtoremove is the old class you have.
  • Class to add is the new class that you want to add.
  • 100 is the timeout delay during which the class is changed.

Good Luck.

@Salman A 2014-01-18 09:28:05

I use the following vanilla JavaScript functions in my code. They use regular expressions and indexOf but do not require quoting special characters in regular expressions.

function addClass(el, cn) {
    var c0 = (" " + el.className + " ").replace(/\s+/g, " "),
        c1 = (" " + cn + " ").replace(/\s+/g, " ");
    if (c0.indexOf(c1) < 0) {
        el.className = (c0 + c1).replace(/\s+/g, " ").replace(/^ | $/g, "");
    }
}

function delClass(el, cn) {
    var c0 = (" " + el.className + " ").replace(/\s+/g, " "),
        c1 = (" " + cn + " ").replace(/\s+/g, " ");
    if (c0.indexOf(c1) >= 0) {
        el.className = c0.replace(c1, " ").replace(/\s+/g, " ").replace(/^ | $/g, "");
    }
}

You can also use element.classList in modern browsers.

@shingokko 2012-05-05 02:46:22

I would use jQuery and write something like this:

jQuery(function($) {
    $("#some-element").click(function() {
        $(this).toggleClass("clicked");
    });
});

This code adds a function to be called when an element of the id some-element is clicked. The function appends clicked to the element's class attribute if it's not already part of it, and removes it if it's there.

Yes you do need to add a reference to the jQuery library in your page to use this code, but at least you can feel confident the most functions in the library would work on pretty much all the modern browsers, and it will save you time implementing your own code to do the same.

Thanks

@ThiefMaster 2012-06-13 14:38:56

You only have to write jQuery in its long form once. jQuery(function($) { }); makes $ available inside the function in all cases.

@moka 2013-04-11 10:13:36

As well you could extend HTMLElement object, in order to add methods to add, remove, toggle and check classes (gist):

HTMLElement = typeof(HTMLElement) != 'undefiend' ? HTMLElement : Element;

HTMLElement.prototype.addClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    if (string[i] && !new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)').test(this.className)) {
      this.className = this.className.trim() + ' ' + string[i];
    }
  }
}

HTMLElement.prototype.removeClass = function(string) {
  if (!(string instanceof Array)) {
    string = string.split(' ');
  }
  for(var i = 0, len = string.length; i < len; ++i) {
    this.className = this.className.replace(new RegExp('(\\s+|^)' + string[i] + '(\\s+|$)'), ' ').trim();
  }
}

HTMLElement.prototype.toggleClass = function(string) {
  if (string) {
    if (new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className)) {
      this.className = this.className.replace(new RegExp('(\\s+|^)' + string + '(\\s+|$)'), ' ').trim();
    } else {
      this.className = this.className.trim() + ' ' + string;
    }
  }
}

HTMLElement.prototype.hasClass = function(string) {
  return string && new RegExp('(\\s+|^)' + string + '(\\s+|$)').test(this.className);
}

And then just use like this (on click will add or remove class):

document.getElementById('yourElementId').onclick = function() {
  this.toggleClass('active');
}

Here is demo.

@zero_cool 2014-08-18 19:28:29

this one is a little verbose...here is a very succinct solution...jsfiddle.net/jdniki/UaT3P

@moka 2014-08-21 08:36:56

Sorry @Jackson_Sandland but you've totally missed the point, which is not to use jQuery at all.

@alfred 2012-10-17 12:21:20

Here's my version, fully working:

function addHTMLClass(item, classname) {
    var obj = item
    if (typeof item=="string") {
        obj = document.getElementById(item)
    }
    obj.className += " " + classname
}

function removeHTMLClass(item, classname) {
    var obj = item
    if (typeof item=="string") {
        obj = document.getElementById(item)
    }
    var classes = ""+obj.className
    while (classes.indexOf(classname)>-1) {
        classes = classes.replace (classname, "")
    }
    obj.className = classes
}

Usage:

<tr onmouseover='addHTMLClass(this,"clsSelected")'
onmouseout='removeHTMLClass(this,"clsSelected")' >

@Quentin 2012-10-17 12:25:42

That will break class foobar if you try to remove class foo. The JS in the intrinsic event handler attributes was broken before being edited. The 4 year old accepted answer is much better.

@alfred 2012-10-17 12:27:42

thanks, i fixed it (not the prefix problem). it's the old accepted answer that have a bug with the regexp.

@rosell.dk 2016-10-17 12:11:08

The code still have the foobar problem. See the test here

@Hiren Kansara 2011-05-28 07:19:25

Change an element's CSS class with JavaScript in ASP.NET:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not Page.IsPostBack Then
        lbSave.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbSave.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
        lbCancel.Attributes.Add("onmouseover", "this.className = 'LinkButtonStyle1'")
        lbCancel.Attributes.Add("onmouseout", "this.className = 'LinkButtonStyle'")
    End If
End Sub

@Tyilo 2011-08-05 17:44:12

You could also just do:

document.getElementById('id').classList.add('class');
document.getElementById('id').classList.remove('class');

And to toggle a class (remove if exists else add it):

document.getElementById('id').classList.toggle('class');

@John 2011-10-27 17:16:59

I believe this is HTML5 dependent.

@ELLIOTTCABLE 2011-11-14 14:34:14

You’ll need Eli Grey’s classList shim.

@Lloyd 2012-01-24 10:24:28

worth noting this doesn't work in IE versions less than 8..

@doubleJ 2012-10-29 04:13:49

Mozilla Developer Network states that it doesn't work, natively, in Internet Explorers less than 10. I find the statement to be true, in my testing. Apparently, the Eli Grey shim is required for Internet Explorer 8-9. Unfortunately, I couldn't find it on his site (even with searching). The shim is available on the Mozilla link.

@andreszs 2014-08-02 23:13:55

Feature not supported until a few hours ago (added on IE10 and Android 3)

@Ajedi32 2015-06-15 15:56:52

@Nick Humphrey 2015-07-29 08:47:38

atow "classList" has partial support in IE10+; no support for Opera Mini; else full support in remaining standard browsers: caniuse.com/#search=classlist

@Wilf 2015-09-06 16:54:53

I think the Eli Grey shim can be found here...

@Squirrl 2016-03-27 18:43:12

i love how little u made me read

@Eric Wendelin 2008-10-12 20:33:06

You can use node.className like so:

document.getElementById('foo').className = 'bar';

This should work in IE5.5 and up according to PPK.

@Eric Sebasta 2015-10-09 20:33:15

this would overwrite any and all other classes on the object... so it is not that simple.

@Gopal Krishna Ranjan 2011-12-08 09:36:57

This is working for me:

function setCSS(eleID) {
    var currTabElem = document.getElementById(eleID);

    currTabElem.setAttribute("class", "some_class_name");
    currTabElem.setAttribute("className", "some_class_name");
}

@Roman Polen. 2012-05-08 11:19:58

Excellent answer! Just left to add : Set for each CSS class name for selector to specify a style for a group of class elements

@Lukasz 'Severiaan' Grela 2012-07-19 12:29:25

This works for me on FF, but when I've tried to use el.className = "newStyle"; it didn't worked, why?

@Oriol 2015-02-11 15:54:32

You can use el.setAttribute('class', newClass) or better el.className = newClass. But not el.setAttribute('className', newClass).

@PseudoNinja 2011-09-20 15:26:08

Using pure JavaScript code:

function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}

function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}

function replaceClass(ele, oldClass, newClass){
    if(hasClass(ele, oldClass)){
        removeClass(ele, oldClass);
        addClass(ele, newClass);
    }
    return;
}

function toggleClass(ele, cls1, cls2){
    if(hasClass(ele, cls1)){
        replaceClass(ele, cls1, cls2);
    }else if(hasClass(ele, cls2)){
        replaceClass(ele, cls2, cls1);
    }else{
        addClass(ele, cls1);
    }
}

@Jaider 2012-04-20 20:40:37

@Ben Flynn 2011-11-26 21:04:12

Just to add on information from another popular framework, Google Closures, see their dom/classes class:

goog.dom.classes.add(element, var_args)

goog.dom.classes.addRemove(element, classesToRemove, classesToAdd)

goog.dom.classes.remove(element, var_args)

One option for selecting the element is using goog.dom.query with a CSS3 selector:

var myElement = goog.dom.query("#MyElement")[0];

@roenving 2008-10-12 20:16:33

No offense, but it's unclever to change class on-the-fly as it forces the CSS interpreter to recalculate the visual presentation of the entire web page.

The reason is that it is nearly impossible for the CSS interpreter to know if any inheritance or cascading could be changed, so the short answer is:

Never ever change className on-the-fly !-)

But usually you'll only need to change a property or two, and that is easily implemented:

function highlight(elm){
    elm.style.backgroundColor ="#345";
    elm.style.color = "#fff";
}

@nickf 2008-10-12 20:46:20

i've never experienced any performance issues with switching CSS classes myself. I think whatever performance hit there might be, it's far outweighed by the messiness of having styles/presentation mixed up in your javascript.

@roenving 2008-10-12 20:51:41

Hrm, obviously you never tested it ... In a realtime application consisting of thousands of rows nested with other elements I recognized a delay of several seconds, remaking it only to change properties it wasn't possible to recognize delay ...

@Peter Boughton 2008-10-12 21:49:36

Why would you even want thousands of rows nested with other elements? Also, what operating system & browser was this delay with?

@eyelidlessness 2008-10-13 03:33:52

If changing a className is causing noticeable performance problems, you have much bigger problems in the structure and design of your page/app. If not, shaving off a few milliseconds is not a good reason to pollute your application logic with styles.

@Jason 2009-12-08 22:19:04

this is the worst idea ever. changing classes is by far and away the easiest and cleanest way to update your CSS on the fly.

@Erik Olson 2011-06-24 15:39:43

To the “thousands of rows” unbelievers: doxygen. Hierarchical, collapsible menus in a side frame. IE7 had fatal issues with this so I used Firefox.

@Alex Jolig 2016-01-31 19:00:14

I'm wondering why you haven't deleted your answer yet! (it's 2016)

@Krease 2016-06-10 16:47:49

@AlexJolig - the user hasn't logged in since 2009

@Mr Anderson 2016-09-01 20:01:56

This is the second-most downvoted answer on the site.

@Lajos Meszaros 2017-04-18 11:25:29

I think "don't do it in the first place" is not an acceptable answer for "how to do it".

@Lajos Meszaros 2017-04-18 11:32:04

So instead of changing a class you go with writing inline styles by hand. You are taking CSS's job. By the way, if you edit the style attribute, it will also redraw the page as it would if you would have changed the class. "obviously you never tested it" - show us some exact data on how your solution is faster. And please don't give us data like "It's 40% faster, when you execute 20 million changes" or something like that.

@Eric Bailey 2009-12-08 22:15:12

The line

document.getElementById("MyElement").className = document.getElementById("MyElement").className.replace(/\bMyClass\b/','')

should be:

document.getElementById("MyElement").className = document.getElementById("MyElement").className.replace('/\bMyClass\b/','');

@Dylan 2011-08-14 21:46:48

Incorrect. The RegEx is delimeted by the forward slashes. Adding quotes causes it to fail in IE, returning the string of the class you're trying to remove rather than actually removing the class.

@Jon Galloway 2008-10-12 20:12:16

This is easiest with a library like jQuery:

<input type="button" onClick="javascript:test_byid();" value="id='second'" />

<script>
function test_byid()
{
    $("#second").toggleClass("highlight");
}
</script>

@roenving 2008-10-12 20:20:49

What does the javascript: pseudo-protocol do in a script-event ... It seems totally stupid to tell the javascript-interpretator, that it should treat script in a script-event as script !-) Only use of the javascript: pseudo-protocol is where you instead would use an url !o]

@Quentin 2008-10-13 08:19:27

In that context, it isn't the pseudo-protocol - it's a loop label ... only there is no loop for it TO label.

@kzh 2011-03-09 20:32:35

Actually, that is not a pseudo-protocol, it is interpreted as a JavaScript label, like what you can use in a loop. One could easily do onClick="myScriptYo:do_it();". But, please, don't do it.

Related Questions

Sponsored Content

3 Answered Questions

88 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6089549 View
  • 7592 Score
  • 88 Answer
  • Tags:   javascript arrays

86 Answered Questions

[SOLVED] How to validate an email address in JavaScript

38 Answered Questions

[SOLVED] How do I loop through or enumerate a JavaScript object?

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

55 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

58 Answered Questions

[SOLVED] How do I redirect to another webpage?

36 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

38 Answered Questions

[SOLVED] How do you get a timestamp in JavaScript?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

Sponsored Content