Screenshot of collapse button for an open details element
JavaScript

Collapse an Open Details Element (JavaScript)

The <details> HTML element is really great. And paired with <summary> you’ve got all you really need to make easy-to-read expandable/collapsable sections of a document. But I recently wanted to have at the bottom of each segment a quick way to close the expanded details segment I’d just scrolled through. By default, you can simply click on the <summary> element you used to open it. But what if your sections are long enough that that has drifted off the top of your screen? That’s the situation I was in that led me to want to write as little JavaScript as possible to reach up to the top from the bottom of my (long) details section and collapse it. So we’re going to explore how to collapse an open details element in this article.

So here’s how I did it. To do any internet-searchers a solid, straight-to-code for you TL;DR-ers:

<details open>
    <summary><h2>Header</h2></summary>
    <p>Lots of content&hellip;</p>
    <p>Lots of content</p>
    <p>You get the idea&hellip;</p>
    <button onclick="this.parentElement.removeAttribute('open')">Collapse section</button>
</details>

A Few More Details 😉 About My Project

For a little personal project, I’ve got some elements under headings that it makes sense to expand and collapse. They’re basic titles of segments of a document. And these segments of the document can get a little long. But once I read a segment, I want it collapsed so I can easily glance back up the document and see where I’ve come from.

So, I want those content sections collapsed, but often the summary I’ve put at the top has gone off screen as I’ve read. (And I’ll be honest, I’m so lazy that sometimes it’s not off-screen, just too far for my lazy mouse cursor. 🤪)

Anyway, I was thinking, “It’d be nice if at the bottom of my <details> element it was easy to collapse it.” So that’s what I set out to do. And I’m not sure if it was Google’s increasing decrepitude (having lost the war against human & AI SEO-optimized to kingdom come content farms, they’re devaluing any new content, perhaps?), but I couldn’t find my answer. I wonder if the details HTML element is too new for anyone to have wanted this? Or maybe I just phrased it wrong. Anyway I decided to build it myself and write it up here, in the hopes that I have enough Google-juice to help the next poor soul with the same thought I had. Let me save you the 15 minutes of JavaScript learning and debugging!

Understanding the JavaScript to Collapse a Details Section

You’ve already seen the full code of my collapsing-from-the-bottom solution above, but in case anyone is confused, let go into a little more detail about what’s going on.

First, we have a fairly basic details element, with the required summary as well:

<details open>
    <summary><h2>Header</h2></summary>
    <p>Lots of content&hellip;</p>
    <p>Lots of content</p>
    <p>You get the idea&hellip;</p>
</details>

Nothing too interesting there. The <details> element is now well supported by most every browser we care about.

At the bottom of that section we add a button. My thinking here — I’m no accessibility expert — is that functionality-wise this is a button, a thing triggering an action. If someone has more knowledge here and thinks this *should not* be a button, I’m all ears. (In the comments or my contact form, please and thank you.)

Anyway, because of how little JavaScript we need here, I put it inline in the button in the most old-school way I could. So here’s that button again:

<button onclick="this.parentElement.removeAttribute('open')">Collapse section</button>

To be explicit here, HTML elements support a number of embedded-JavaScript attributes, onclick is probably the most common and useful. But between those double-quotes is pure simple JavaScript. Or if you prefer, the JavaScript I used to collapse an open details element alone:

this.parentElement.removeAttribute('open')

What’s happening here is that we’re starting with the context of the button. So this essentially means the button element. From there, I know that given the shape of my HTML markup, the parentElement will always be the details element. (If you’re not so sure about the shape of your markup, you might want to write a little more JS.)

Then, to close an open <details> element, we must remove the open attribute. (In my HTML, I have my details start open, <details open>. And as MDN notes, you must remove the open attribute. Because of the way details functions, setting it to false doesn’t do ANYTHING. Once removed, the <details> element will naturally be collapsed.

You Might Want More JavaScript: scrollIntoView()

Now I was pretty happy with this at first. But as I started to use it more, I actually found that I’d written too little JavaScript. As I said, my document segments were sometimes kind of long. And I found that as I collapsed the section above, I’d be lost half-way down the next section after I collapsed the <details> segment above.

So I ended up with this button:

<button onclick="this.parentElement.removeAttribute('open'); this.parentElement.scrollIntoView()">
&uarr; Collapse section
</button>

Which includes these TWO lines of JavaScript:

this.parentElement.removeAttribute('open');
this.parentElement.scrollIntoView();

This solution is a little jumpy, but I always know where I am. As you might expect from its rather-clear name, element.scrollIntoView() assures that our (newly collapsed) details element is still on screen. This way I always know I’m seeing the full section that’s just under the section which I’ve just collapsed.

(Since I mentioned accessibility earlier, I think people who are very sensitive to movement might *hate* this behavior. Heck, they might now even like the initial way I was collapsing <details> elements. I’m no expert there, so please consult one before using this in widely-used projects.)

Takeaways about Collapsing an Open Details Element

The core highlights here: the details element is awesome, it’s OK to embed small bits of JavaScript in your onclick attribute, and you must remove the open attribute, and not simply make it false.

Hope this was a helpful exploration of how to collapse an open details element with JavaScript!

Standard

Leave a Reply

Your email address will not be published. Required fields are marked *