Show and Hide Content Easily With details and summary HTML Tags
Vitor Paladini

Vitor Paladini @vtrpldn

About: A software engineer that really likes working with user interfaces. Writes mostly JS at getcircuit.com. Loves cooking.

Joined:
May 18, 2019

Show and Hide Content Easily With details and summary HTML Tags

Publish Date: Sep 30 '20
112 18

Here's a neat little trick:

You can use the <details> and <summary> HTML tags to create a simple accordion/collapsible UI.

Summary/Details tags example

The only problem here is that it looks rather plain and uninteresting.

But nothing that a few lines of CSS can't fix! Here's how it looks with just a little bit of styling.

Remember that you can click the "Open Sandbox" button and edit the styles yourself. I'm sure that you can make it look even nicer. 😄

Oh, and here's the CSS, take a look. It features a couple hacks with padding and box-shadow to make the "border" look consistent but, other than that, it is a pretty simple change.

/* The --padding variable help us control 
the <details> and <summary> spacing */
:root {
  --padding: 16px;
}

details {
  padding: 0 var(--padding);
  box-shadow: inset 0 0 0 4px;
  border-radius: 4px;
}
details[open] {
  padding-bottom: var(--padding);
}

details > summary {
  display: flex;
  padding: var(--padding);
  margin: 0 calc(var(--padding) * -1);
  border-radius: 4px;
  font-size: 24px;
  cursor: pointer;
  justify-content: space-between;
  list-style: none; /* Hides the default arrow */
}
details[open] > summary {
  box-shadow: 0 4px;
}
/* Adds an icon when the <details> is closed... */
details > summary::after {
  content: "+";
}
/* ...and switches it when <details> is open */
details[open] > summary::after {
  content: "-";
}
/* Removes the ugly default arrow on Chrome */
details > summary::-webkit-details-marker {
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

I love how much you can accomplish with plain HTML and CSS.

And by using standard HTML tags you get great accessibility for free!

But wait, there's more!

You can go even further and transform these two tags into a powerful and, dare I say, extremely reusable component.

Let's add some React to it! ⚛️

These two tags work very well with React's component composition pattern.

So you can just go ahead and create a component to help you toggle stuff more consistently and easier.

Look:

Then you can import that component and use it like so:

This is a great component to have on your toolbelt for when you need to implement a few accordions quickly.

Thanks for checking out this neat little trick 👋

I hope it comes in handy soon!

Do you have a suggestion for a neat little trick? Leave it on the comments!

Oh! And remember to check the other articles on this series below. They are some spicy little nuggets of webdev knowledge.

Cover photo by Dominik Vanyi on Unsplash


Hey, let's connect 👋

Follow me on Twitter and let me know you liked this article!

And if you really liked it, make sure to share it with your friends, that'll help me a lot 😄

Comments 18 total

  • Christian Kaisermann
    Christian KaisermannSep 30, 2020

    Your brain is beautiful, sir!

    • Vitor Paladini
      Vitor PaladiniSep 30, 2020

      Thanks for your support, Chris

      You also have a magnificent cranial anatomy 🧠

  • Vitor Paladini
    Vitor PaladiniSep 30, 2020

    Thanks! ☃️

  • Giorgos Sarigiannidis
    Giorgos SarigiannidisSep 30, 2020

    This is a nice and simple trick which I wanted to further investigate myself too at some point. Mostly, I wanted to investigate 2 basic topics:

    • Is it semantically correct to use it as an FAQ or should the markup be different on such cases?
    • Can you apply CSS animations?

    Do you happen to have any good resources on the above?

    • Vitor Paladini
      Vitor PaladiniSep 30, 2020

      Hey Giorgos, great questions.

      Is it semantically correct to use it as an FAQ or should the markup be different on such cases?

      I'd say so, yeah! The says W3C spec says that "The rest of the element’s contents represents the additional information or controls."

      A FAQ answer seems like additional information in my book.

      Can you apply CSS animations?

      Hmm... To a degree, but animating display and height is particularly tricky. I've found some examples but none particularly good. I'll give it a try and update the article if I find a way to do it 🙂

  • Cezar Augusto
    Cezar AugustoSep 30, 2020

    Hey @vtrpldn , nice post! Great to know about summary/details, love dynamic HTML elements.

    btw is it possible (semantically?) to have the component to display in an "open" state by default? Would be cool! :)

    • Vitor Paladini
      Vitor PaladiniSep 30, 2020

      Hey, Cezar. Thanks!

      Yes, you can add an open attribute to it, like so: <details open> and the details box will start in an opened state

      • Cezar Augusto
        Cezar AugustoSep 30, 2020

        cool, thanks! been learning nice stuff from your posts here on DEV, keep them coming!

  • Ayush Kumar Singh
    Ayush Kumar SinghSep 30, 2020

    Amazing

  • Uriel Bitton
    Uriel BittonSep 30, 2020

    Very nice. I'm curious to know how do you make the action clickable without any JS

    • Vitor Paladini
      Vitor PaladiniSep 30, 2020

      That's just how <details> + <summary> works. It is quite like how you can make a range slider with <input type="range"> 🙂

  • Lakindu Kariyawasam
    Lakindu KariyawasamOct 1, 2020

    what a tutorial !
    simple, but elegant trick..
    thank you!

  • Vitor Paladini
    Vitor PaladiniOct 1, 2020

    Thanks, Felipe! I love finding and sharing these little nuggets of webdev, let me know if you have a suggestion 😄

  • Amitsheo
    AmitsheoFeb 1, 2022

    Hi,

    This is nice,
    I have a query.

    I just want to display tag content only when media is less than 600px, but more than that want to disable tag property but content should be displayed. I donot want to "display :none "

    Please help me regarding this.

Add comment