The details and summary tags to display on-demand content using only HTML

- 👤 Andrés Cruz

🇪🇸 En español

The details and summary tags to display on-demand content using only HTML

Continuing to talk about some little-known tags:

Many times we use JavaScript libraries without further ado to add components that do not natively exist in our browser; like when we want to show a simple dialog in HTML, we use Bootstrap or one of the thousand and one JavaScript libraries we can find on the Internet; one of those cases is when we want to display on-demand content, which we can do very easily using the details and summary tags.

The details and summary HTML Tags: complete guide with practical examples

Sometimes we assume we need a JavaScript library for everything: menus, accordions, dropdowns... I myself used to do that, until I discovered that HTML already came with an integrated gem: the <details> and <summary> tags. Since then, every time I want to show content "on demand," I solve it natively, cleanly, and more lightly.

In this guide, I teach you everything: from the basics to advanced patterns, including CSS tricks, compatibility, accessibility, and real cases I've used in my own projects.

What the details and summary tags are and what they are for

The <details> and <summary> tags form a small "disclosure widget": a block that shows a header and, when clicked, reveals hidden content. It's practically a native HTML accordion.

The idea of the native HTML5 “accordion”

  • The <summary> acts as the clickable header.
  • The <details> is the container that hides or shows its internal content.

When you don't define a <summary>, the browser automatically creates one (sometimes with the text "Details"). But it is almost always best to customize it.

When to use them and why to avoid unnecessary libraries

Many times we use libraries like Bootstrap just to create basic effects. I used to do it: I needed to show a small panel, and I ended up importing half a framework. When I discovered these tags, I stopped doing it because they work in most modern browsers, weigh virtually nothing, and are accessible by default.

How a <details> works step by step

Minimum structure (with and without <summary>)

<details> <summary>See more</summary> <p>Content hidden at the start.</p> </details>

If you omit <summary>, the browser generates it and you won't be able to style it the same way, so it's good practice to always declare it.

The open attribute: showing content by default

If you want the panel to start expanded, just use:

<details open> <summary>Title</summary> <p>Content visible from the start.</p> </details>

When I wanted to show images ("My cool photo," as in your example), I used open to highlight important content without forcing the user to click.

What happens in the DOM when it expands

When a user opens a <details>, the browser automatically adds the open attribute. This allows you to:

  • Style it with details[open]
  • Detect changes with the toggle event
  • Know if it is open from JavaScript using element.open

Functioning of the details and summary tags

These tags must be in the body of our web, in other words our body, and when configured, they offer a header that the user can click on to show the rest of the content; in other words, the content we define in details is shown when we click on a header which we define with summary.

This post explains in detail the functioning of the details tag which allows showing/hiding content on demand or through user interaction on this field:

HTML details example

details and summary in practice

Before we start defining these details and summary tags together, let's see an example of what we explained earlier; so click on the header and you will see "Hello World" content appear:

Title

Hello World

Click on the text above to show the secondary content.

The previous experiment corresponds to the following HTML:

    <details> <summary>Title</summary> <p>Hello World</p> </details> 

The details tag is responsible for demarcating the relevant content, while the content covered by the summary tag is responsible for demarcating the secondary content which is shown on demand; it's that simple.

Always show the content open

If you want to show the secondary content open, you must specify the open attribute within the details element:

Tiger

tiger image

My cool photo.

Click on the text above to hide the secondary content.

The previous experiment corresponds to the following HTML:

<details open> <summary>Tiger</summary> <img src="tigre-200.jpg"> <p>My cool photo.</p> </details> 

The only difference with the previous example is that this one has the open attribute; also with this attribute it is possible to define specific CSS rules for these tags as we will see in the next section:

CSS for the details and summary tags

Like any other selector, it is possible to define styles for these tags; we can apply whatever we want, change the font style, color, size, margins and much more:

details[open] {} details[open] summary {} 
The content inside summary can be any HTML, no matter how complex, and it should not only consist of simple text.

Basic examples to get started

"Hello World" expandable example

Just as you showed in your own article:

<details> <summary>Title</summary> <p>Hello World</p> </details>

This example is perfect for understanding the clicking mechanism.

Example with text, images, and mixed elements

<details> <summary>Tiger</summary> <img src="tigre-200.jpg" alt="Tiger Photo"> <p>My cool photo.</p> </details>

I use this pattern when I need to show brief descriptions or small galleries without cluttering the design.

Mini information panel

<details> handles complex HTML very well: tables, lists, and so on.

<details> <summary>Order #545645144</summary> <table> ... </table> </details>

I even used it to reproduce receipts or concentrated information during layout testing.

CSS Styles for details and summary

Base styles: typography, colors, and spacing

You can apply any style as if it were a normal container:

details { margin: 1rem 0; } summary { cursor: pointer; font-weight: bold; }

Customize the arrow with ::marker and ::before

Some browsers allow styling the default arrow:

summary::marker { color: #222; font-size: 130%; }

If you want to remove it and use your own icon (which I did more than once), you can:

summary::-webkit-details-marker { display: none; } 
details summary::before { content: "+ "; } 
details[open] summary::before { content: "- "; }

Conditional styles with details[open]

This allows you to highlight the open state, as you did in your menu example:

details[open] summary {

 background-color: #08B;

 color: #FFF;

}

Replace the icon with an image

details summary::before { 
background-image: url(icon.png); 
width: 20px; 
height: 20px; 
display: inline-block; 
}

Based on what was explained above, we can come up with some experiments like the ones shown below.

Online shopping detail

As commented previously, you can define CSS composed of multiple nested tags, as happens with tables; here the summary and details tags work perfectly:

Order #545645144
Date10/12/2015 12:45 pm
Order number#545645144
CourierUPS
Address1600 Ave NW, Washington, DC 20500, USA.
Order
  • Apple iPhone 5.......... $799.00

Amazon Fire TV Stick.... $39.00

  • PlayStation TV.......... $79.00
  • Total................... $917.00

The previous experiment corresponds to the following HTML:

   <details>
         <summary>Order #545645144</summary>
         <table>
             <tr>
                 <td>Fecha</td>
                 <td>10/12/2015 12:45 pm</td>
             </tr>
             <tr>
                 <td>Orden número</td>
                 <td>#545645144</td>
             </tr>
             <tr>
                 <td>Courier</td>
                 <td>UPS</td>
             </tr>
             <tr>
                 <td>Dirección</td>
                 <td>1600 Ave NW, Washington, DC 20500, EEUU.</td>
             </tr>
             <tr>
                 <td>Pedido</td>
                 <td>
                     <ul>
                         <li>Apple iPhone 5.......... $799.00</li>
                         <li>Amazon Fire TV Stick.... $39.00</li>
                         <li>PlayStation TV.......... $79.00</li>
                         <li>Total................... $917.00</li>
                     </ul>
                 </td>
             </tr>
         </table>
     </details>

You can also change the color, size, etc. of the summary indicator located on the left using the details-marker selector.

summary::-webkit-details-marker { color: #222; font-size: 130%; } 

Control listings with summary

Not only can the details tag be used to display an information panel like the previous case, we can also place an additional control panel like the following experiment:

The previous experiment corresponds to the following HTML:

<details> <summary>Menu</summary> 
<ul> <li><a href="#Comprar">Buy</a></li>
 <li><a href="#Devolver">Return</a></li> 
 <li><a href="#Comparar">Compare</a></li> </ul> 
 </details> 

Also, we use the selector:

details[open] 
summary{ background-color: #08B; color:#FFF; border-radius:5px 5px 0 0; } 

To change the appearance of the summary element or the header when it is open.

CSS transitions...

We can use other properties like transition to define smooth changes:

The previous experiment corresponds to the following HTML:

<details> <summary>Menu</summary> <ul> <li><a href="#Comprar">Buy</a></li> <li><a href="#Devolver">Return</a></li> <li><a href="#Comparar">Compare</a></li> </ul> </details> 

A consideration for the next example (If you don't want to show the small indicator):

summary::-webkit-details-marker { display: none; } 

It is also possible to change the indicator icon to a customized one; for example, an image:

The previous experiment corresponds to the following HTML:

<details> 
<summary>Menu</summary> 
<ul> 
<li><a href="#Comprar">Buy</a></li> 
<li><a href="#Devolver">Return</a></li> 
<li><a href="#Comparar">Compare</a></li> </ul> 
</details> 

To change the indicator icon, the after or before selector is used:

details summary:before {
 display: inline-block; width: 32px; height: 18px; margin-right: 8px; content: ""; float:left; background-image: url(navigation_collapse.png); } 

Advanced patterns with details

Menus and action lists without JavaScript

<details> <summary>Menu</summary> 
<ul> 
<li>
<a href="#Comprar">Buy</a></li> <li>
<a href="#Devolver">Return</a></li> <li>
<a href="#Comparar">Compare</a></li> </ul> 
</details>

I used this pattern for secondary menus without needing JS.

Exclusive accordion using the name attribute

Modern feature (2024–2025):

<details name="acordeon" open> 
<summary>Section 1</summary> 
<p>Content</p> 
</details> 
<details name="acordeon"> <summary>Section 2</summary> 
<p>Content</p> </details>

Only one opens at a time.

Smooth transitions with CSS

Although <details> does not animate the opening by default, you can animate internal elements:

details[open] div {
 transition: opacity 0.3s ease; opacity: 1; 
 }

Integration in FAQ and tables

<details> works excellently for frequently asked questions or product sheets.

Accessibility and best practices

  • <summary> should always be the first child element.
  • Avoid putting too many interactive elements inside the <summary> (links, inputs).
  • Ensure sufficient contrast if you style it.
  • Keyboard navigation works in most modern browsers.
  • Safari does not yet include <summary> in the standard tab order.

Browser compatibility and frequent problems

In your article you mentioned that Firefox did not support <details>. That was true years ago, but as of 2020, Firefox, Chrome, Edge, and Safari support it, although:

  • Safari has focus issues.
  • Some older browsers do not allow styling ::marker.
  • Hidden content may or may not be indexed depending on the browser.

If you need total compatibility, you can use a very light polyfill or maintain a CSS-based fallback version.

Comparison: native HTML accordion vs. JavaScript solutions

  • Performance
    • Native HTML will always be lighter.
  • Maintainability
    • Less code = fewer errors.
  • Accessibility
    • <details> is accessible out of the box.
  • When to use each one
    • Native HTML: simple dropdowns, FAQ, light panels, secondary menus.
    • JavaScript: when you need complex animations, state synchronization, or integration with advanced forms.

Frequently Asked Questions (FAQ)

  • Can I use <details> as an accordion without JavaScript?
    • Yes, you can even create exclusive accordions with the name attribute.
  • How do I make it start open?
    • Use the boolean open attribute.
  • Can I change the default arrow that appears?
    • Yes, with ::marker, ::before, or by removing the native marker.
  • Is it accessible?
    • Generally, yes. Although Safari still has focus limitations.
  • Does hiding the content affect SEO?
    • It is not usually a problem. Search engines do read the content, although some browsers do not include it in certain internal searches.

Conclusions

The <details> and <summary> tags are little treasures hidden in HTML. When I discovered them, I stopped adding unnecessary libraries just to display expandable content, and since then I use them every time I want a lightweight, semantic, and accessible solution.

Plus, with a little CSS, you can turn them into accordions, menus, information panels, and even elegant visual indicators.

In short, it is a very curious and somewhat unknown element provided in HTML that can have multiple possibilities when laying out HTML and CSS, and let's hope that the folks at Mozilla soon decide to incorporate support in upcoming versions of their browser.

I agree to receive announcements of interest about this Blog.

The details and summary tags are ideal for displaying on-demand content by demarcating relevant content, while summary is responsible for demarcating secondary content which is displayed on demand without using JavaScript.

| 👤 Andrés Cruz

🇪🇸 En español