Show and Hide HTML Elements with JavaScript

Master the fundamental techniques for controlling element visibility, from CSS properties to efficient toggle patterns that power modern interactive web applications.

Understanding CSS Display Property

The CSS display property represents the most common approach to hiding elements in web development. When you set display: none on an element, the browser removes it entirely from the document flow, as if the element never existed. This means the element takes up no space on the page, and surrounding content flows to occupy its former area.

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

// Hide the element
element.style.display = 'none';

// Show the element
element.style.display = 'block';

To reveal a hidden element, set its display value to a visible state such as block, inline, or inline-block depending on the element's desired layout behavior. For more advanced approaches to managing DOM elements, explore our guide on locating DOM elements using selectors.

The display property approach works well for completely removing elements from visual consideration. When you hide an element with display: none, the browser doesn't just make it invisible--it genuinely removes it from the rendering tree. This has important implications: the element cannot receive focus, screen readers ignore it entirely, and search engines may interpret it differently than visually hidden content. For many interactive patterns like modals and expanding sections, this behavior is precisely what you want.

Understanding the difference between removing elements entirely and simply making them invisible is crucial for building accessible interfaces. Our JavaScript fundamentals resources cover these concepts in greater depth for developers building modern web applications.

Working with CSS Visibility Property

The CSS visibility property offers an alternative approach that preserves the space occupied by the hidden element. When you set visibility: hidden, the element becomes invisible but maintains its footprint in the document layout. The gap where the element would appear remains, and neighboring elements don't shift to fill the space.

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

// Hide but preserve space
element.style.visibility = 'hidden';

// Show the element
element.style.visibility = 'visible';

This distinction matters significantly for certain design patterns. Consider a pricing table where you want to disable certain tiers--using visibility: hidden keeps the table columns aligned properly while hiding the disabled option. Similarly, in responsive layouts where you need to maintain consistent spacing, the visibility property prevents jarring layout shifts when elements appear and disappear.

However, like display: none, elements with visibility: hidden are not accessible to screen readers and cannot receive keyboard focus. For scenarios where you need to hide content visually while maintaining accessibility, see our section on screen reader considerations below.

The visibility property proves particularly useful in CSS transitions where you want to animate opacity while keeping the element's layout footprint intact. By combining visibility: hidden with opacity transitions, you create smooth fade effects that don't disrupt surrounding content positioning.

Efficient Toggle Patterns with classList

The classList API offers methods for adding, removing, and toggling CSS classes, keeping your JavaScript focused on state management while CSS handles presentation. This approach centralizes styling logic, making it easier to update visual treatments and ensuring consistent behavior across your application.

// Add a class
element.classList.add('hidden');

// Remove a class
element.classList.remove('hidden');

// Toggle a class
element.classList.toggle('hidden');

// Check if class exists
if (element.classList.contains('hidden')) {
 // Element is currently hidden
}

The toggle pattern proves particularly elegant for interactive components. A single click handler can handle both showing and hiding without conditional logic examining the current state. The browser efficiently applies and removes the associated CSS rules, and you can leverage CSS transitions for smooth animations.

By defining your .hidden class in your stylesheet with appropriate display or visibility values, you create a reusable mechanism applicable to any element. This approach aligns with modern component-based development patterns where visual states are defined declaratively in CSS rather than imperatively in JavaScript. For more on memory-efficient DOM manipulation techniques, see Frontend Masters' guide on patterns for memory efficient DOM manipulation.

Key Techniques for Element Visibility

Master these fundamental approaches for controlling what users see on your web pages.

Display Property

Use display: none to completely remove elements from layout, and display: block/inline/inline-block to show them again. Ideal for modals and expanding sections.

Visibility Property

Hide elements while preserving their space with visibility: hidden, ideal for maintaining layout consistency in tables and responsive designs.

classList Toggle

Leverage the classList API for clean, maintainable state management with reusable CSS classes. The preferred approach for modern applications.

Performance First

Prefer hiding existing elements over creating new ones to minimize DOM operations and memory churn. Critical for frequently toggled components.

Performance Best Practices

Understanding when to hide versus when to create and destroy elements significantly impacts application performance. The fundamental principle is simple: prefer hiding and showing existing DOM elements over creating new ones and removing them entirely. This approach minimizes expensive DOM operations, reduces memory churn, and improves rendering performance, especially for frequently toggled elements.

Why Hiding Wins

Keeping elements in the DOM and simply toggling their visibility avoids triggering layout recalculations and garbage collection. When you remove an element and later reinsert it, the browser must:

  1. Parse HTML and construct DOM nodes
  2. Calculate layout and positioning
  3. Paint the affected regions

In contrast, toggling a class or style on an existing element requires only a style recalculation and potential repaint.

State Preservation

Hiding preserves the component's internal state, event listeners, and previously loaded content. For components that users open and close repeatedly--modals, dropdowns, collapsible sections--this approach provides instant responsiveness. The performance difference becomes particularly noticeable on mobile devices and in applications with complex interfaces.

By maintaining a pool of hidden but ready-to-use elements, you can provide snappy interactions even on resource-constrained devices. This pattern aligns with our performance optimization strategies for building fast, responsive web applications that users love.

Accessibility Considerations

Hiding elements affects how assistive technologies interact with your page, making accessibility an essential consideration. Elements hidden with display: none or visibility: hidden are effectively invisible to screen readers and removed from the accessibility tree.

Screen Reader Only Content

For content that should be hidden visually but remain accessible, use the .sr-only pattern:

.sr-only {
 position: absolute;
 width: 1px;
 height: 1px;
 padding: 0;
 margin: -1px;
 overflow: hidden;
 clip: rect(0, 0, 0, 0);
 white-space: nowrap;
 border: 0;
}

ARIA Attributes for Interactive Components

When implementing accordions or tabs, use ARIA attributes to communicate state:

function toggleAccordion(button) {
 const content = button.nextElementSibling;
 const isExpanded = button.getAttribute('aria-expanded') === 'true';

 button.setAttribute('aria-expanded', !isExpanded);
 content.classList.toggle('expanded');
}

The aria-expanded attribute indicates whether a collapsible section is open or closed, while aria-hidden can programmatically remove elements from the accessibility tree when they should be ignored. These techniques ensure your interactive components work seamlessly with screen readers and other assistive technologies. For comprehensive accessibility guidance, explore our resources on building inclusive web experiences.

Common Implementation Patterns

Accordions

Accordions expand and collapse content sections. Use aria-expanded to communicate state and CSS transitions for smooth animations. When implementing accordions, consider how the content will behave when expanded--ensuring adequate space and proper scroll behavior creates a polished user experience.

Modals

Modals require focus management--trapping focus within the modal while open--and handling background scroll lock to prevent the main page from scrolling. Our CSS masking techniques can help create sophisticated modal overlays and effects.

Conditional Content

For form validation messages or context-dependent UI, class-based toggling provides clean separation between data and presentation:

/* State-based classes */
.is-hidden { display: none !important; }
.is-visible { display: block !important; }
.has-error { border-color: #dc3545; }
.is-loading { opacity: 0.7; pointer-events: none; }

This approach creates reusable states that communicate intent, making code more readable and maintainable. When team members encounter .is-loading, they immediately understand the element's purpose without examining its specific display or visibility values.

These patterns form the foundation of interactive web applications that respond dynamically to user input while maintaining clean, maintainable code architecture.

Frequently Asked Questions

Build Interactive Web Experiences

Our web development team specializes in creating dynamic, performant interfaces using modern JavaScript patterns.