How To Change Class Of An Element By Click

Master JavaScript class manipulation techniques to create interactive web experiences. Learn className, classList, and best practices for dynamic styling.

Understanding CSS Class Manipulation in JavaScript

CSS classes serve as the primary mechanism for applying styles to HTML elements, but their power extends far beyond static presentation. By modifying which classes an element possesses at runtime, developers can create rich, interactive experiences without resorting to inline styles or other less maintainable approaches.

When you change a class like .active or .expanded, you're applying an entire set of pre-defined styles that can be coordinated across multiple elements. This approach is fundamental to modern web development, enabling interfaces that respond dynamically to user interactions.

For developers working with complex interfaces, understanding class manipulation pairs well with learning CSS architecture patterns that help maintain scalable stylesheets as projects grow.

Why Use Class Changes Instead of Inline Styles

Choosing to modify CSS classes rather than setting inline styles offers several compelling advantages:

  • Separation of concerns: Keeps presentation logic separate from JavaScript code
  • Maintainability: Styles can be tweaked in CSS without touching JavaScript
  • Performance: Modern browsers optimize CSS class application through sophisticated caching mechanisms
  • Consistency: Avoids tight coupling between styling decisions and logic

Inline styles, by contrast, couple your styling decisions directly to your JavaScript logic. If you need to adjust colors, spacing, or transitions, you're forced to modify both your CSS and your JavaScript code. Class-based manipulation keeps your codebase clean and maintainable as projects grow in complexity.

Class Manipulation Methods

Choose the right approach for your use case

className Property

Direct string assignment for simple use cases

classList API

Modern approach with add, remove, toggle, and replace methods

Event Integration

Trigger class changes on click events and user interactions

Performance Optimized

Best practices for efficient DOM manipulation

Method 1: The className Property

The className property provides the most direct way to manipulate an element's CSS classes. This property has been available since the earliest versions of JavaScript and remains a reliable tool for class manipulation today.

Basic Syntax

// Reading the current class
const element = document.getElementById('myElement');
const currentClasses = element.className;

// Setting a new class (replaces all existing classes)
element.className = 'new-class';

Adding Classes While Preserving Existing Ones

const element = document.getElementById('myButton');

// Adding a class while preserving existing ones
element.className = element.className + ' active';

// Using template literals (more readable)
element.className = `${element.className} active`;

Limitations of className

  • Treats entire class attribute as a single string
  • No built-in methods for adding/removing individual classes
  • Requires manual string parsing for checking class existence
  • Can be error-prone with string concatenation

While className works for simple use cases, modern JavaScript development typically favors the classList API for its cleaner syntax and robust feature set.

For more advanced CSS techniques that work well with class manipulation, explore our guide on modern CSS selectors.

className with Click Event
1// Using className with click event2const toggleButton = document.getElementById('toggleButton');3 4toggleButton.addEventListener('click', function() {5 if (this.className === 'collapsed') {6 this.className = 'expanded';7 } else {8 this.className = 'collapsed';9 }10});

Method 2: The classList API

The classList property, introduced in HTML5, provides a far more elegant solution. It exposes a DOMTokenList object with intuitive methods for adding, removing, toggling, and checking classes. This API addresses all the shortcomings of className while providing a cleaner, more readable syntax.

Adding Classes with add()

const button = document.getElementById('myButton');

// Add a single class
button.classList.add('active');

// Add multiple classes at once
button.classList.add('visible', 'animated');

Removing Classes with remove()

const navigation = document.getElementById('mainNavigation');

// Remove a single class
navigation.classList.remove('mobile-open');

// Remove multiple classes
navigation.classList.remove('animating', 'temporary-state');

Toggling Classes with toggle()

The toggle() method is perfect for on/off states:

const toggleSwitch = document.getElementById('themeToggle');

toggleSwitch.addEventListener('click', function() {
 document.body.classList.toggle('dark-mode');
});

Replacing Classes with replace()

const statusIndicator = document.getElementById('status');

// Replace one class with another
const wasReplaced = statusIndicator.classList.replace('loading', 'ready');

if (wasReplaced) {
 console.log('Status updated successfully');
}

Checking Class Existence with contains()

const alertBox = document.getElementById('alert');

if (alertBox.classList.contains('visible')) {
 console.log('The alert is currently visible');
}

The classList API is the recommended approach for modern JavaScript development. It provides cleaner, more maintainable code that handles edge cases automatically.

Building interactive interfaces with class manipulation is a core skill for front-end developers working on dynamic web applications.

document.querySelectorAll('.accordion-header').forEach(header => {
 header.addEventListener('click', function() {
 const accordionItem = this.closest('.accordion-item');
 accordionItem.classList.toggle('expanded');
 });
});

Performance Best Practices

Minimize DOM Reflows

Each class change triggers style recalculations. Batch multiple changes for better performance:

// Less efficient - multiple reflows
element.classList.add('step-1');
element.classList.add('step-2');
element.classList.add('step-3');

// More efficient - single reflow
element.classList.add('step-1', 'step-2', 'step-3');

Cache Element References

// Cache the element reference
const menuButton = document.getElementById('menuButton');
const mobileMenu = document.getElementById('mobileMenu');

menuButton.addEventListener('click', function() {
 mobileMenu.classList.toggle('open');
});

Event Delegation for Dynamic Elements

// Single listener handles dynamically created elements
document.getElementById('accordionContainer').addEventListener('click', function(event) {
 if (event.target.classList.contains('accordion-toggle')) {
 const accordionItem = event.target.closest('.accordion-item');
 accordionItem.classList.toggle('expanded');
 }
});

Following these performance patterns ensures your JavaScript implementations remain responsive even as your applications grow in complexity.

For developers looking to deepen their understanding of JavaScript performance, our ES2018 features guide covers additional modern techniques for writing efficient code.

Frequently Asked Questions

Ready to Build Interactive Web Experiences?

Our web development team specializes in creating dynamic, responsive interfaces using modern JavaScript techniques.