731

Could anyone let me know how to remove a class on an element using JavaScript only? Please do not give me an answer with jQuery as I can't use it, and I don't know anything about it.

ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
Amra
  • 24,780
  • 27
  • 82
  • 92

11 Answers11

1113

The right and standard way to do it is using classList. It is now widely supported in the latest version of most modern browsers:

ELEMENT.classList.remove("CLASS_NAME");

remove.onclick = () => {
  const el = document.querySelector('#el');
  el.classList.remove("red");
}
.red {
  background: red
}
<div id='el' class="red"> Test</div>
<button id='remove'>Remove Class</button>

Documentation: https://developer.mozilla.org/en/DOM/element.classList

user3163495
  • 2,425
  • 2
  • 26
  • 43
Paul Rouget
  • 11,790
  • 2
  • 15
  • 10
  • 2
    FWIW, this works for me on FF 7.0.1, and Chromium 16.0.910.0 – SW. Oct 19 '11 at 01:38
  • 6
    Very nice! That is so much simpler than regular expressions and splitting `className` into parts and manually traversing them. – Victor Zamanian Feb 12 '13 at 23:16
  • 24
    @dzhioev - I believe because it is relatively new and not supported in older browsers (IE support starts at IE10) – Tom Pietrosanti Apr 05 '13 at 13:58
  • 11
    On the MDN page there is a shim provided for older browsers. – oxygen Jun 07 '13 at 16:52
  • This is probably the [article about removing a class with fallback](https://hacks.mozilla.org/2010/01/classlist-in-firefox-3-6/) he was talking about. – surfmuggle Dec 29 '13 at 23:13
  • 1
    This gets even better with [this polyfill](https://github.com/eligrey/classList.js/blob/master/classList.js). –  Apr 11 '14 at 21:07
  • 4
    ELEMENT.classList has both 'add' and 'remove', btw. – Kamilius Oct 30 '14 at 11:57
  • Checked with Chromium in Ubuntu 14.04, and it works as well. So apparently they've caught up. – v010dya Dec 02 '14 at 19:49
  • Works in mobile Chrome/30.0.0.0 – Nawaf Alsulami Dec 22 '14 at 00:00
  • More about classList support [http://caniuse.com/#search=classList](http://caniuse.com/#search=classList) and [https://developer.mozilla.org/en-US/docs/Web/API/Element.classList#Browser_compatibility](https://developer.mozilla.org/en-US/docs/Web/API/Element.classList#Browser_compatibility) – Mario Jan 11 '15 at 17:47
  • 2
    Best answer here! Adds the least complexity to your JS if you need to do this in plain JS. – hzhu Feb 10 '15 at 17:25
  • 1
    classList also can toggle() ,add() and check for class (contains()) and support multiple class operations. I think this is the best answer (+1) – prasadmadanayake May 11 '15 at 06:18
  • 1
    I just checked the [can I use link](http://caniuse.com/#search=classList) his feature seems to be working now for all major browsers except for Opera Mini and partial support for IE 11 – Rarepuppers Dec 15 '16 at 17:13
  • 10 years later. I think it's the best solution. – Zolbayar Apr 13 '20 at 12:13
  • 2
    Why bother checking if the class is there before calling `.remove` if the function doesn't throw any errors if the class isn't there? If you remove the if statement, then JavaScript doesn't have to scan through the class list twice every time it is true. – apokaliptis May 14 '21 at 10:47
  • 1
    IMO checking the condition: `if (el.classList.contains("red"))` isn't necessary, see official `remove()` docs: https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/remove – long Apr 06 '22 at 11:42
530
document.getElementById("MyID").className =
    document.getElementById("MyID").className.replace(/\bMyClass\b/,'');

where MyID is the ID of the element and MyClass is the name of the class you wish to remove.


UPDATE: To support class names containing dash character, such as "My-Class", use

document.getElementById("MyID").className =
  document.getElementById("MyID").className
    .replace(new RegExp('(?:^|\\s)'+ 'My-Class' + '(?:\\s|$)'), ' ');
Ωmega
  • 42,614
  • 34
  • 134
  • 203
ЯegDwight
  • 24,821
  • 10
  • 45
  • 52
  • 13
    Correct me if I'm wrong but I think that your 1st argument on `replace` must be a regex, so without enclosing it in quotes: `.replace(/\bMyClass\b/,'')`. But then 'MyClass' must to be a literal, otherwise maybe creating the regex dinamically could work: `.replace(new RegExp('\\b' + myClass + '\\b'),'')` – Pau Fracés Jan 08 '13 at 12:12
  • Also the ID of the element used in your example is "element_id" and not "MyID" – Pau Fracés Jan 08 '13 at 12:16
  • 3
    @PauFracés Check the edit history. The inconsistency got introduced by someone else. – ЯegDwight Jan 08 '13 at 12:20
  • @ЯegDwight But as Nicholas Pickering suggested, that code wont work until it becomes a regexp. See my previous comment – Pau Fracés Jan 08 '13 at 12:34
  • 55
    The use of the [word boundary metacharacter `\b`](http://www.regular-expressions.info/wordboundaries.html) is not suitable here, because the word boundary occurs also between a word character `[A-Za-z0-9_]` and the dash `-` character. Therefore a class name e.g. *'different-MyClass'* would also be replaced, resulting in *'different-'*. There is a better solution which [matches whitespace characters around the class name](http://stackoverflow.com/a/9959811/686534). – Adam Jun 03 '13 at 15:53
  • 2
    I'm also removing a space if its there: `domNode.className.replace(new RegExp(" ?\\b"+cssClass+"\\b"),'')` – B T May 15 '14 at 07:16
  • 1
    ill just copy paste this here since this where google leads me to not the page with right answer linked in Adam comment. `function removeClass(e,c) {e.className = e.className.replace( new RegExp('(?:^|\\s)'+c+'(?!\\S)') ,'');}` – Muhammad Umer Jun 28 '15 at 17:25
  • didn't work in my case but I like your thoughts – Venzentx Aug 14 '15 at 15:30
  • There are faster methods to remove class than using RegExp, especially if you're going to use it as a polyfill. See http://jsperf.com/removeclass-methods – thdoan Nov 24 '15 at 08:51
  • IE says the object doesnt support replace.... – mrg95 Dec 02 '18 at 03:44
  • If there are multiple instances of the class, for example: `class1 My-Class My-Class My-Class My-Class` this regex won't remove all of them. That's because it removes the \s on both sides of a match, which makes the next match invalid because you stole its spaces! – Obscerno Jul 25 '21 at 01:54
  • What worked for me was replacing `'(?:\\s|$)'` with `'(?=\\s|$)'` (turning it from a non-capture group to positive lookahead). It checks if the space exists without matching it. If you do this you can also make the replacement text `''` instead of `' '` because you're leaving a space (or the end of the line) untouched. – Obscerno Jul 25 '21 at 01:54
62

Here's a way to bake this functionality right into all DOM elements:

HTMLElement.prototype.removeClass = function(remove) {
    var newClassName = "";
    var i;
    var classes = this.className.split(" ");
    for(i = 0; i < classes.length; i++) {
        if(classes[i] !== remove) {
            newClassName += classes[i] + " ";
        }
    }
    this.className = newClassName;
}
Matthew
  • 12,892
  • 6
  • 42
  • 45
  • 3
    Very elegant and most applicable to the question. – Alex Beynenson Dec 03 '12 at 15:07
  • 7
    Add an if wrapper [if (typeof HTMLElement.prototype.removeClass !== "function") {] to make this answer most elegant in case browsers add support for removeClass in the future.. – Matthieu Cormier Jan 16 '13 at 14:43
  • @Matthew A logoical programmatic way. Appreciate it. Looks cross-browser too. Is it??? – Rajesh Paul Oct 05 '13 at 07:17
  • 1
    You can also split classes by \t \n \r and \s+, your split-nonregex doesn't take that into account. – Stefan Steiger Dec 01 '14 at 21:20
  • 3
    Add a trim() at the end of return to remove redundant spaces when function is used more then once (such as toggling an active/deactivate state). – Sam Nov 20 '15 at 21:26
  • @Sam, Added a trim before setting newClassName and tested in JSFiddle: https://jsfiddle.net/bs2o7wgz/1/ – Sharif Dec 23 '15 at 01:31
47
div.classList.add("foo");
div.classList.remove("foo");

More at https://developer.mozilla.org/en-US/docs/Web/API/element.classList

joseconstela
  • 727
  • 8
  • 12
  • 7
    Nice, too bad supports starts with IE 10 and Android 3. Why they didn't code this stuff 10 years ago?.. – andreszs Aug 02 '14 at 23:09
  • 2
    @Andrew To be honest the entire world of web technologies looks like a big pile of ideas thrown together without system or consistency... – Nearoo Feb 05 '17 at 00:53
44

Try this:

function hasClass(ele, cls) {
  return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
    
function removeClass(ele, cls) {
  if (hasClass(ele,cls)) {
    var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
    ele.className=ele.className.replace(reg,' ');
  }
}
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Keith Rousseau
  • 4,435
  • 1
  • 22
  • 28
27

Edit

Okay, complete re-write. It's been a while, I've learned a bit and the comments have helped.

Node.prototype.hasClass = function (className) {
    if (this.classList) {
        return this.classList.contains(className);
    } else {
        return (-1 < this.className.indexOf(className));
    }
};

Node.prototype.addClass = function (className) {
    if (this.classList) {
        this.classList.add(className);
    } else if (!this.hasClass(className)) {
        var classes = this.className.split(" ");
        classes.push(className);
        this.className = classes.join(" ");
    }
    return this;
};

Node.prototype.removeClass = function (className) {
    if (this.classList) {
        this.classList.remove(className);
    } else {
        var classes = this.className.split(" ");
        classes.splice(classes.indexOf(className), 1);
        this.className = classes.join(" ");
    }
    return this;
};


Old Post
I was just working with something like this. Here's a solution I came up with...
// Some browsers don't have a native trim() function
if(!String.prototype.trim) {
    Object.defineProperty(String.prototype,'trim', {
        value: function() {
            return this.replace(/^\s+|\s+$/g,'');
        },
        writable:false,
        enumerable:false,
        configurable:false
    });
}
// addClass()
// first checks if the class name already exists, if not, it adds the class.
Object.defineProperty(Node.prototype,'addClass', {
    value: function(c) {
        if(this.className.indexOf(c)<0) {
            this.className=this.className+=' '+c;
        }
        return this;
    },
    writable:false,
    enumerable:false,
    configurable:false
});
// removeClass()
// removes the class and cleans up the className value by changing double 
// spacing to single spacing and trimming any leading or trailing spaces
Object.defineProperty(Node.prototype,'removeClass', {
    value: function(c) {
        this.className=this.className.replace(c,'').replace('  ',' ').trim();
        return this;
    },
    writable:false,
    enumerable:false,
    configurable:false
});

Now you can call myElement.removeClass('myClass')

or chain it: myElement.removeClass("oldClass").addClass("newClass");

Duncan
  • 1,530
  • 15
  • 20
  • 3
    I'm very late here, but I have an example case where this would not work: Consider an element that has classes testClass and testClass2. (class="testClass testClass2") We wish to remove testClass from the element. Result using your method: class="2" This is why breaking it into an array is favourable. Of course, it is still possible to achieve the correct result using pure string manipulation, but it becomes more complex. If you don't want a mess of code you'll need to use Regex. The advantage of using an array is that the code is easily readable. – Joshua Walsh May 15 '14 at 02:06
  • @YM_Industries You're right! I'll edit my post. – Duncan May 16 '14 at 20:01
  • @Knu Native `Element.classList.add()` doesn't support the space in `"one two"`. – Duncan Mar 06 '15 at 11:05
  • @Knu What about `".one.two"`, `("one", "two", ...)`, `["one","two"]`, `{"0":"one","1":"two"}`... etc. I'll leave non-standard parameter handling to the person implementing their code. :) – Duncan Mar 06 '15 at 18:41
  • `classList` **isn't** supported in **IE < 11**. You can use regex instead : `this.className = this.className.replace(new RegExp('(?:^|\\s)' + className + '(?:\\s|$)'), '').trim();` – Flox May 10 '17 at 08:02
  • @Flox No need for that, non-'classList' browsers are already handled. Not to mention that regex is fairly heavy and not needed in this instance. – Duncan May 11 '17 at 08:14
  • i dont think `.contains` is supported, by older browsers. – alphapilgrim Dec 12 '17 at 17:38
  • Having `Element.prototype` instead of `Node.prototype` makes more sense because only elements would have `class`. – iMatoria May 21 '18 at 05:10
20

It's very simple, I think.

document.getElementById("whatever").classList.remove("className");
Taryn
  • 242,637
  • 56
  • 362
  • 405
LivinKalai
  • 311
  • 2
  • 4
  • 8
    This has poor cross-browser support. Internet Explorer doesn't support it in any version prior to 10. https://developer.mozilla.org/en-US/docs/Web/API/element.classList#Browser_compatibility – Justin Morgan - On strike Aug 26 '13 at 20:58
  • 3
    This to me seems like the right answer. If you are worried about cross browser use a polyfill. https://github.com/eligrey/classList.js – Shannon Poole Aug 28 '13 at 16:28
  • 3
    @ShannonPoole Sometimes you just need to do a simple task in an IE8-compatible way and you don't want it to depend on library support or a heavy polyfill. – acjay Feb 19 '15 at 12:53
  • 3
    @acjay and sometimes you throw caution to the wind and just follow the modern standard :) – Shannon Poole Feb 20 '15 at 10:13
  • 1
    To support IE, you can use **regex** instead : `this.className = this.className.replace(new RegExp('(?:^|\\s)' + className + '(?:\\s|$)'), '').trim();` – Flox May 10 '17 at 08:04
10

try:

function removeClassName(elem, name){
    var remClass = elem.className;
    var re = new RegExp('(^| )' + name + '( |$)');
    remClass = remClass.replace(re, '$1');
    remClass = remClass.replace(/ $/, '');
    elem.className = remClass;
}
scunliffe
  • 62,582
  • 25
  • 126
  • 161
5
var element = document.getElementById('example_id');
var remove_class = 'example_class';

element.className = element.className.replace(' ' + remove_class, '').replace(remove_class, '');
Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
Tornike
  • 49
  • 1
  • 1
0

I use this JS snippet code :

First of all, I reach all the classes then according to index of my target class, I set className = "".

Target = document.getElementsByClassName("yourClass")[1];
Target.className="";
Amir
  • 1,009
  • 1
  • 9
  • 11
-7
document.getElementById("whatever").className += "classToKeep";

With the plus sign ('+') appending the class as opposed to overwriting any existing classes

Ringo
  • 3,795
  • 3
  • 22
  • 37
les
  • 564
  • 7
  • 19