Skip to main content

Hiding / removing elements in DOM using JavaScript

4 min read

Older Article

This article was published 8 years ago. Some information may be outdated or no longer applicable.

There are several ways to hide (or outright remove) elements from the DOM using JavaScript. Each one behaves differently, and picking the wrong one can trip you up.

Let’s work with a simple HTML page:

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="app.css" />
    <title>Hide elements in DOM using JavaScript</title>
  </head>

  <body>
    <main id="main">
      <div class="first">
        <p>First <code>div</code> element</p>
      </div>
      <div class="second">
        <p>Second <code>div</code> element</p>
      </div>
    </main>

    <footer>
      <button id="hideFirst">Hide first div</button>
      <button id="showFirst">Show first div</button>
    </footer>

    <script src="app.js"></script>
  </body>
</html>

Two <div> elements, two <button> elements. The buttons will show and hide the first <div>. The <div>s have different backgrounds on purpose so you can actually see what’s happening.

We’ll walk through four approaches.

visibility: hidden

The quickest way to hide an element is to set its CSS visibility to hidden:

const firstDiv = document.querySelector('.first');
const btnHide = document.getElementById('hideFirst');
const btnShow = document.getElementById('showFirst');

btnHide.addEventListener('click', () => {
  firstDiv.style.visibility = 'hidden';
});

btnShow.addEventListener('click', () => {
  firstDiv.style.visibility = '';
});

Run this and you’ll notice the element disappears, but the space it occupied stays put. The element still sits in the DOM tree. It’s just invisible. A CSS property changed, nothing more.

To bring it back, set the visibility property to an empty string.

style.display

Setting display to none also hides the element without ripping it from the DOM. But this time, the element stops claiming space on the page. The second <div> slides up to fill the gap:

const firstDiv = document.querySelector('.first');
const btnHide = document.getElementById('hideFirst');
const btnShow = document.getElementById('showFirst');

btnHide.addEventListener('click', () => {
  firstDiv.style.display = 'none';
});

btnShow.addEventListener('click', () => {
  firstDiv.style.display = 'block';
});

Using the hidden attribute

The hidden attribute takes a boolean value and does roughly the same thing as display: none:

const firstDiv = document.querySelector('.first');
const btnHide = document.getElementById('hideFirst');
const btnShow = document.getElementById('showFirst');

btnHide.addEventListener('click', () => {
  firstDiv.hidden = true;
});

btnShow.addEventListener('click', () => {
  firstDiv.hidden = false;
});

The <div> stays in the DOM tree but doesn’t occupy space. The second <div> moves into its place. Under the hood, a style gets applied:

div.first {
  display: none;
}

If you add a display CSS property with any value other than none, the element will show up regardless of whether the HTML hidden attribute is present.

.remove()

This one actually tears the element out of the DOM tree entirely:

const firstDiv = document.querySelector('.first');
const btnHide = document.getElementById('hideFirst');
const btnShow = document.getElementById('showFirst');

btnHide.addEventListener('click', () => {
  firstDiv.remove();
});

btnShow.addEventListener('click', () => {
  if (!document.querySelector('.first')) {
    const div = document.createElement('div');
    div.classList.add('first');
    const paragraph = document.createElement('p');
    paragraph.innerHTML = 'First <code>div</code> element';
    div.appendChild(paragraph);
    const main = document.getElementById('main');
    main.insertBefore(div, main.firstChild);
  }
});

Once you’ve called .remove(), putting the element back gets messy. You need to rebuild it from scratch. That’s the trade-off.

There’s a simpler (slightly riskier) approach. We captured a reference to the first <div> at the top, so we can just re-insert it:

btnShow.addEventListener('click', () => {
  if (!document.querySelector('.first')) {
    const main = document.getElementById('main');
    main.insertBefore(firstDiv, main.firstChild);
  }
});

Be careful with this in larger codebases. You might not always have that reference lying around.

Styling an element

Pulling an element out of the DOM wipes all dynamically added event listeners and styles clean. You can test this by adding another button to the HTML:

<button id="addSytle">Add style</button>

And some code to apply a style dynamically:

const btnAddStyle = document.getElementById('addSytle');
btnAddStyle.addEventListener('click', () => {
  firstDiv.style.color = 'black';
});

If you rebuild the element manually, that styling vanishes. If you re-insert it using the stored reference, the styling sticks.

Conclusion

Four ways to hide and remove DOM elements, each with different consequences. Pick the one that fits your situation, but keep an eye on the side effects.