Creating a collapsible section with nothing but HTML
Jordan Finneran

Jordan Finneran @jordanfinners

About: Tech Lead, Physics Grad, Video/Photographer, Tech Fan, All Round Tweeter!

Joined:
Apr 23, 2019

Creating a collapsible section with nothing but HTML

Publish Date: Dec 23 '20
128 20

Contents

  1. Intro
  2. Details
  3. Examples
  4. Summary

Intro

I love creating User Interfaces (UI) and often times well need a section to expand and collapse for example in a FAQ section.

I used to reach for NPM and install a library to help, until I discovered that you can do this with pure HTML elements!

They aren't perhaps the most obviously named:

They have pretty great browser support.

Details

The details element is the element to contain the content we want to show and hide.
The summary element is caption to describe what is hidden, in an FAQ section this might be the question and the answer is hidden in the details element until it is expanded.

You can toggle the details element open and closed with JavaScript if needed in your use case by setting the open attribute on it.

It is also pretty straightforward to style the arrow, you can see this in the example below where I've used an emoji instead but this can be anything you want.

Examples

Shut up and show me the code.

Summary

In summary, you can use what browsers give you to create an expanding and collapsing section.
It will be accessible for all users as its semantic HTML.
It will be super quick to load as there is only HTML and a few lines of CSS.
It will be responsive to any screen size.

Happy building!

What else would you like to see in this Web Dev series?

Comments 20 total

  • Madza
    MadzaDec 23, 2020

    proof that if you know the basic tech to the core, you don't always need frameworks, libraries, and all the other 'shiny' things 😉

    • Jordan Finneran
      Jordan FinneranDec 23, 2020

      There so much you can do with HTML and CSS!
      There is also a place for shiny things but I'd always advocate using what the browser gives you for free first! :D

  • Jordan Finneran
    Jordan FinneranDec 23, 2020

    Thank you, this means alot!
    I'm going to cover off plenty more in this series! 😀

  • Fang Jin
    Fang JinDec 23, 2020

    The tricky part of this piece is always the height of the invisible elements as well as the potential height when it's not visible.

    • Jordan Finneran
      Jordan FinneranDec 27, 2020

      Yes, the times I've used it so far, its normally in a group of a few collapsible sections so I've never had to worry about the height too much as I use CSS flex :)

      • Jordan Finneran
        Jordan FinneranDec 27, 2020

        What tricks are you having with height? Maybe its something we could work through :D

  • Alvaro Montoro
    Alvaro MontoroDec 23, 2020

    Nice post + reference to Hitchhiker's Guide to the Galaxy? Take all the ❤️🦄!

  • Gift Opia
    Gift OpiaDec 23, 2020

    Wow this is actually very handy.... Reduces the call for bootstrap or other frameworks classes

  • Adam Crockett 🌀
    Adam Crockett 🌀Dec 23, 2020

    Hmm, I knew about this but I didn't think it had styling potential. If it's cross browser for evergreens then this is worth knowing for sure. Symantec and accessibility 🦾

  • Manuel Sommerhalder
    Manuel SommerhalderDec 24, 2020

    be aware, the summary/details element is not as accessible as a well implemented accordion pattern.

    • Jordan Finneran
      Jordan FinneranDec 27, 2020

      Do you have any links or anything to read up on this? :)
      Its semantic HTML elements, so I couldn't see much being better.

      • Manuel Sommerhalder
        Manuel SommerhalderDec 27, 2020

        the first point is that it is not even a semantic HTML element for an accordion, it's much more a disclose widget (also mentioned here accessibleculture.org/articles/201...).

        You can compare them at the WAI-ARIA practices site:
        w3.org/TR/wai-aria-practices-1.1/#...
        w3.org/TR/wai-aria-practices-1.1/#...

        The article above also states some accessibility problems the screen readers have with details/summary element. I quote:

        If you must have one or more links nested in the summary, arrange them so that they are not the first things within the summary element. And even if you manage this, you should recognise that:
        
        - these links still won't be in any way clearly identifiable to users of VoiceOver in Safari;
        - these links still won't be available to JAWS in FF or Window-Eyes in both FF and IE when these screen readers are in Browse Mode; and,
        - JAWS users with IE will have a less than ideal experience reading the summary's content.
        
        Enter fullscreen mode Exit fullscreen mode

        and another article:
        scottohara.me/blog/2018/09/03/deta...

  • Felix
    FelixJul 13, 2023

    Love this succinct article - very helpful and it shows that sometimes implementing elements in CSS and JS is overkill!

  • Ismael Benitez
    Ismael BenitezAug 22, 2023

    Thank you!

  • Rebecca
    RebeccaSep 10, 2023

    Hey - this is a little bit of a "hail Mary" since this post is 3 years old, but I've tried everything I can think of to get this to work and so maybe I should just ask!

    I love this code - it's so simple and functions just as I wanted it to. However, when I implemented it on my site and wrapped a <li> tag around the <span class="icon">, the rotate animation stopped working. I assume this is because the code is not looking for a li span.icon, it's looking for a span.icon that's nested directly within a summary tag only. However, I can't seem to edit the code to tell it to expect the li tag and rotate anyway. I've tried all kinds of variations to indicate parent, child, descendant relationships and it still refuses to rotate. I must be missing something obvious but I can't think what it is. Does that make sense? Do you know what the answer might be?

    Thank you so much!

    • Jordan Finneran
      Jordan FinneranSep 23, 2023

      Hey, I wouldn't recommend nesting the span in a li tag. As ifs not really indicating a list item.
      I would look at wrapping the content you want in the li tag.

      If you did want to do that however you could change the following in CSS.
      Anywhere you see summary span.icon change it to summary li>span.icon

      The arrow indicates the span is a child of the li element 😊
      Hope that helps

Add comment