Question
How can I remove a CSS class from an HTML element using plain JavaScript, without using jQuery?
Short Answer
You will learn how to select an element and remove one or more CSS classes with modern vanilla JavaScript. You will also see how to check whether a class exists, handle older code patterns, and use class removal safely in real interfaces.
Concept
A CSS class is a reusable label attached to an HTML element through its class attribute. CSS uses that label to apply styles, and JavaScript can add, remove, or inspect it to change an interface dynamically.
The recommended JavaScript API is element.classList. It provides methods for working with individual class names without manually editing a string.
To remove a class, use:
element.classList.remove("class-name");
For example, a modal might have an is-open class while visible. Removing is-open can hide it if the CSS is written to respond to that class.
.modal {
display: none;
}
.modal.is-open {
display: block;
}
modal.classList.remove("is-open");
This separation is important in real applications:
- CSS defines how each state looks.
- HTML provides the structure.
- JavaScript changes state by adding or removing classes.
This approach is usually cleaner than setting many individual inline styles from JavaScript.
Mental Model
Think of an element's classes as removable stickers on a box.
- An HTML element is the box.
- Each CSS class is a sticker, such as
selected,hidden, orerror. - CSS checks for stickers and changes the box's appearance.
classList.remove()peels off one specific sticker without affecting the others.
For example, removing hidden from an element may make it visible, while its other stickers, such as card and featured, remain attached.
Syntax and Examples
Use classList.remove() on an element reference.
element.classList.remove("class-name");
Remove a class from an element selected by ID
<p id="notice" class="message success">Saved successfully.</p>
const notice = document.getElementById("notice");
notice.classList.remove("success");
After this code runs, the element becomes:
<p id="notice" class="message">Saved successfully.</p>
The message class remains because only success was removed.
Remove several classes
remove() accepts multiple class names.
const panel = document.querySelector(".panel");
panel.classList.remove("is-open", "is-loading", "has-error");
Remove a class after a click
<button id="close-button">Close</button>
<div id="banner" class="banner is-visible">Welcome!</div>
const closeButton = document.getElementById("close-button");
const banner = document.getElementById("banner");
closeButton.addEventListener("click", () => {
banner.classList.remove("is-visible");
});
The event listener waits for a click, then removes the class that represents the visible state.
Step by Step Execution
Consider this HTML and JavaScript:
<div id="menu" class="menu is-open">Menu content</div>
const menu = document.getElementById("menu");
menu.classList.remove("is-open");
Step by step:
-
The browser parses the HTML. The
divbegins with two classes:menuandis-open. -
document.getElementById("menu")finds the element whoseidismenu. -
The variable
menunow refers to that DOM element. -
menu.classListexposes the element's individual class names. -
.remove("is-open")removes onlyis-open. -
The final HTML class attribute is effectively:
class="menu" -
The browser recalculates applicable CSS. If
.is-opencontrolled visibility or animation, that styling no longer applies.
Here is a traceable click example:
const button = document.querySelector("#dismiss");
const alertBox = document.querySelector(".alert");
button.addEventListener("click", () => {
alertBox.classList.remove("show");
});
Nothing changes when this code is first registered. The class is removed only after the user clicks the element with id="dismiss".
Real World Use Cases
Removing classes is a common way to represent changes in interface state.
- Dismiss notifications: Remove
is-visibleafter a user closes a cookie banner or alert. - Close dialogs and menus: Remove
is-openfrom a modal, navigation menu, dropdown, or side panel. - Clear validation feedback: Remove
is-invalidafter a user corrects a form field. - Stop loading states: Remove
is-loadingonce an API request finishes. - Remove selected styling: Remove
activefrom a previously selected tab, product, or navigation item. - End animations: Remove an animation-triggering class after a CSS transition or animation completes.
- Responsive UI state: Remove a mobile navigation class when a user chooses a link or the viewport changes.
Real Codebase Usage
In production code, classes often describe state with names such as is-open, is-hidden, is-loading, has-error, and is-active. These names make intent easier to understand than visual names such as red-text.
Guard against missing elements
A selector can return null. Check before using classList when the element may not exist on every page.
const banner = document.querySelector(".cookie-banner");
if (banner) {
banner.classList.remove("is-visible");
}
Use a function for repeated UI actions
function closeModal(modal) {
modal.classList.remove("is-open");
modal.setAttribute("aria-hidden", "true");
}
This keeps related state changes together. When hiding interactive content, accessibility attributes may need to change too.
Coordinate related elements
When a menu closes, update both the menu and its trigger button.
function closeMenu(menu, button) {
menu.classList.remove("is-open");
button.setAttribute("aria-expanded", "false");
}
Remove a class from many elements
querySelectorAll() returns a collection. Loop over it to update each matching element.
document.querySelectorAll(".task.is-complete").forEach((task) => {
task.classList.remove("is-complete");
});
Use this deliberately: removing a state from many items is different from changing just one selected item.
Common Mistakes
Calling classList on a selector string
This does not select an element:
// Broken
".menu".classList.remove("is-open");
A string has no classList. Select the DOM element first.
const menu = document.querySelector(".menu");
menu.classList.remove("is-open");
Using a dot in the class name passed to remove()
Dots are used in CSS selectors, not in class names passed to classList.
// Broken
menu.classList.remove(".is-open");
// Correct
menu.classList.remove("is-open");
Replacing every class accidentally
This removes all classes, not only one:
// Usually too destructive
menu.className = "";
Prefer this when removing one class:
menu.classList.remove("is-open");
Running code before the element exists
If JavaScript runs before the browser has parsed the target HTML, the selector may return null.
const menu = document.querySelector(".menu");
menu.classList.remove("is-open"); // Error if menu is null
Place your script near the end of body, use defer on an external script, or wait for DOMContentLoaded.
<script src="app.js" defer></script>
Expecting remove() to add a class back
remove() only removes. For a click that should switch between states, use toggle().
menu.classList.toggle("is-open");
Manipulating className with string replacement
Older code may use this:
menu.className = menu.className.replace("is-open", "");
It is fragile because it can leave extra spaces or accidentally alter part of another class name. Prefer classList.remove() whenever it is available.
Comparisons
| Approach | Best use | Example | Notes |
|---|---|---|---|
classList.remove() | Remove a known class | box.classList.remove("hidden") | Clear and safe for individual classes. |
classList.add() | Apply a state class | box.classList.add("hidden") | The opposite operation. |
classList.toggle() | Switch a class on or off | box.classList.toggle("hidden") | Useful for buttons, menus, and accordions. |
classList.contains() | Check whether a class exists | box.classList.contains("hidden") | Returns true or false. |
className | Read or replace the full class string | box.className = "card" | Can be useful when intentionally replacing all classes, but is easier to misuse. |
| Inline style changes | Change one visual property directly | box.style.display = "none" | Often less maintainable than state classes because styling moves into JavaScript. |
remove() versus toggle()
// Always ensure the menu is closed.
menu.classList.remove("is-open");
// Reverse its current state: open becomes closed, closed becomes open.
menu.classList.toggle("is-open");
Use remove() when the desired final state is definitely known. Use toggle() when the action should invert the current state.
Cheat Sheet
// Select one element
const element = document.querySelector(".card");
// Remove one class
element.classList.remove("is-active");
// Remove multiple classes
element.classList.remove("is-active", "is-loading");
// Check for a class
const active = element.classList.contains("is-active");
// Add a class
element.classList.add("is-active");
// Toggle a class
element.classList.toggle("is-active");
// Force a class off or on
element.classList.toggle("is-active", false);
element.classList.toggle("is-active", true);
Rules to remember:
- Select an actual element before using
classList. - Pass class names without a leading
.. remove()does not throw an error if the specified class is already absent.querySelector()returns the first match ornull.querySelectorAll()returns all matches; loop withforEach().- Prefer
classListover manualclassNamestring editing.
FAQ
How do I remove a class from an element in JavaScript?
Select the element, then call classList.remove().
document.querySelector(".box").classList.remove("active");
Should I include the dot in classList.remove(".active")?
No. Use "active", not ".active". The dot belongs to CSS selectors such as .active used with querySelector().
Can JavaScript remove multiple classes at once?
Yes.
element.classList.remove("active", "loading", "error");
What happens if the class does not exist?
Nothing harmful happens. classList.remove("missing-class") simply leaves the element unchanged.
How do I remove a class from every matching element?
Use querySelectorAll() and loop through the results.
document.querySelectorAll(".item").forEach((item) => {
item.classList.remove("selected");
});
Why does Cannot read properties of null (reading 'classList') appear?
Your selector did not find an element, often because the selector is incorrect or the script ran before the HTML was loaded. Check the selector and use defer or run code after the relevant HTML.
Is className the same as classList?
No. className is the complete class attribute as a string. classList is an API for safely managing individual classes.
Do I need jQuery to remove classes?
No. Modern browsers provide classList.remove() as part of standard JavaScript.
Mini Project
Description
Build a dismissible notification banner using a CSS state class. This pattern is used for announcements, cookie notices, warnings, and success messages. Clicking the close button removes the class that makes the banner visible.
Goal
Create a banner that disappears when the user clicks its Close button.
Requirements
Requirement 1
Keep learning
Related questions
Add a Favicon to a Static HTML Page
Learn how to add a favicon to static HTML pages, use correct paths and icon formats, and troubleshoot browser caching and local-file issues.
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.