Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Designing For TV: Principles, Patterns And Practical Guidance (Part 2)

      September 5, 2025

      Neo4j introduces new graph architecture that allows operational and analytics workloads to be run together

      September 5, 2025

      Beyond the benchmarks: Understanding the coding personalities of different LLMs

      September 5, 2025

      Top 10 Use Cases of Vibe Coding in Large-Scale Node.js Applications

      September 3, 2025

      Building smarter interactions with MCP elicitation: From clunky tool calls to seamless user experiences

      September 4, 2025

      From Zero to MCP: Simplifying AI Integrations with xmcp

      September 4, 2025

      Distribution Release: Linux Mint 22.2

      September 4, 2025

      Coded Smorgasbord: Basically, a Smorgasbord

      September 4, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Drupal 11’s AI Features: What They Actually Mean for Your Team

      September 5, 2025
      Recent

      Drupal 11’s AI Features: What They Actually Mean for Your Team

      September 5, 2025

      Why Data Governance Matters More Than Ever in 2025?

      September 5, 2025

      Perficient Included in the IDC Market Glance for Digital Business Professional Services, 3Q25

      September 5, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      How DevOps Teams Are Redefining Reliability with NixOS and OSTree-Powered Linux

      September 5, 2025
      Recent

      How DevOps Teams Are Redefining Reliability with NixOS and OSTree-Powered Linux

      September 5, 2025

      Distribution Release: Linux Mint 22.2

      September 4, 2025

      ‘Cronos: The New Dawn’ was by far my favorite experience at Gamescom 2025 — Bloober might have cooked an Xbox / PC horror masterpiece

      September 4, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Build Simpler Accordion Menus with HTML

    How to Build Simpler Accordion Menus with HTML

    July 21, 2025

    Accordion menus are everywhere on the web because users want fast answers and smooth navigation.

    They help create clean, organized, and user-friendly interfaces. Many developers still reach for JavaScript to build accordions, which adds avoidable complexities to their projects.

    The HTML <details> element solves this problem with its built-in disclosure widget that toggles content visibility using just a few lines of HTML and optional CSS.

    In this article, we’ll look at an FAQ accordion built using <details>. You can see the final project here.

    Table of Contents

    • What is the HTML <details> Element?

    • An FAQ Accordion Built with the <details> Element

    • Browser Support and Accessibility Considerations

    • Conclusion

    What is the HTML <details> Element?

    The HTML <details> element is a disclosure widget that allows you to hide and show content with a single click. Think of it as a native accordion that comes built into HTML.

    The most common use case for accordions is the Frequently Asked Questions (FAQ) section on many sites. If you’ve seen or interacted with an FAQ, that’s an opportunity to use <details>.

    It has two main components:

    • <details> is the main container tag that opens and closes to display what’s in <summary>.

    • <summary> is a container for the content that is displayed when <details> is clicked.

    💡 In addition to the summary, you can include any HTML text element within the <details> container.

    0d6ebbae-d68d-400f-9209-a83feec273b7

    The image above shows a real-life use case of <details> on the Apple website. In a later section, we’ll learn about the browsers that support it.

    When to Use <details> over JavaScript alternatives

    Unlike JavaScript-based accordions that add weight to your project, <details> offers the same functionality with minimal load and better performance. It also offers built-in keyboard navigation and screen reader support.

    Choose <details> over JavaScript-created accordions when:

    • Building simple accordions or FAQ sections

    • Accessibility, performance, and SEO are a priority

    • You want to avoid JavaScript dependencies

    An FAQ Accordion Built with the <details> Element

    Here’s what our example project looks like:

    Example project using the  element

    This design is by Frontend Mentor (and you can check out the project on Codepen).

    To follow along, you need basic knowledge of HTML and CSS. Since the focus of this article is <details>, we won’t place a lot of emphasis on the starting HTML and CSS code (available on the Codepen above). Instead, we’ll look at one FAQ question with its answer to learn how <details> works.

    How to Use <details>

    To create an accordion with the <details> element, you need both the <details> and <summary> elements, as shown in the starter code below.

    <span class="hljs-tag"><<span class="hljs-name">details</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">summary</span>></span>What is Frontend Mentor, and how will it help me?<span class="hljs-tag"></<span class="hljs-name">summary</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">p</span>></span>Frontend Mentor offers realistic coding challenges to help developers improve their frontend coding skills with projects in HTML, CSS, and JavaScript. It’s suitable for all levels and ideal for portfolio building.<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
    <span class="hljs-tag"></<span class="hljs-name">details</span>></span>
    

    The GIF below will be the result after running the above code. With less than five lines of HTML code, we already have an accordion.

    25c66453-71ba-469c-8dd2-0f1b8e3b9d7f

    Styling <details>

    Now, let’s focus on transforming our basic accordion into something visually appealing (foundational styles can be found on the Codepen). First, we’ll add the icons as SVGs within <summary> with classes (closed-icon and open-icon) to make them easy to style.

    <span class="hljs-tag"><<span class="hljs-name">details</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">summary</span>></span>What is Frontend Mentor, and how will it help me?
      <span class="hljs-tag"><<span class="hljs-name">svg</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"closed-icon"</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"<http://www.w3.org/2000/svg>"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"closed-icon"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"31"</span> <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 30 31"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"none"</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M15 3.3125C12.5895 3.3125 10.2332 4.02728 8.22899 5.36646C6.22477 6.70564 4.66267 8.60907 3.74022 10.836C2.81778 13.063 2.57643 15.5135 3.04668 17.8777C3.51694 20.2418 4.67769 22.4134 6.38214 24.1179C8.08659 25.8223 10.2582 26.9831 12.6223 27.4533C14.9865 27.9236 17.437 27.6822 19.664 26.7598C21.8909 25.8373 23.7944 24.2752 25.1335 22.271C26.4727 20.2668 27.1875 17.9105 27.1875 15.5C27.1835 12.2689 25.8981 9.17131 23.6134 6.88659C21.3287 4.60186 18.2311 3.31653 15 3.3125ZM19.6875 16.4375H15.9375V20.1875C15.9375 20.4361 15.8387 20.6746 15.6629 20.8504C15.4871 21.0262 15.2486 21.125 15 21.125C14.7514 21.125 14.5129 21.0262 14.3371 20.8504C14.1613 20.6746 14.0625 20.4361 14.0625 20.1875V16.4375H10.3125C10.0639 16.4375 9.82541 16.3387 9.64959 16.1629C9.47378 15.9871 9.375 15.7486 9.375 15.5C9.375 15.2514 9.47378 15.0129 9.64959 14.8371C9.82541 14.6613 10.0639 14.5625 10.3125 14.5625H14.0625V10.8125C14.0625 10.5639 14.1613 10.3254 14.3371 10.1496C14.5129 9.97377 14.7514 9.875 15 9.875C15.2486 9.875 15.4871 9.97377 15.6629 10.1496C15.8387 10.3254 15.9375 10.5639 15.9375 10.8125V14.5625H19.6875C19.9361 14.5625 20.1746 14.6613 20.3504 14.8371C20.5262 15.0129 20.625 15.2514 20.625 15.5C20.625 15.7486 20.5262 15.9871 20.3504 16.1629C20.1746 16.3387 19.9361 16.4375 19.6875 16.4375Z"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"#AD28EB"</span>/></span>
      <span class="hljs-tag"></<span class="hljs-name">svg</span>></span> 
      <span class="hljs-tag"><<span class="hljs-name">svg</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"open-icon"</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"<http://www.w3.org/2000/svg>"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"open-icon"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"30"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"31"</span> <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 30 31"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"none"</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M15 3.3125C12.5895 3.3125 10.2332 4.02728 8.22899 5.36646C6.22477 6.70564 4.66267 8.60907 3.74022 10.836C2.81778 13.063 2.57643 15.5135 3.04668 17.8777C3.51694 20.2418 4.67769 22.4134 6.38214 24.1179C8.08659 25.8223 10.2582 26.9831 12.6223 27.4533C14.9865 27.9236 17.437 27.6822 19.664 26.7598C21.8909 25.8373 23.7944 24.2752 25.1335 22.271C26.4727 20.2668 27.1875 17.9105 27.1875 15.5C27.1841 12.2687 25.899 9.17076 23.6141 6.8859C21.3292 4.60104 18.2313 3.31591 15 3.3125ZM19.6875 16.4375H10.3125C10.0639 16.4375 9.82541 16.3387 9.64959 16.1629C9.47378 15.9871 9.37501 15.7486 9.37501 15.5C9.37501 15.2514 9.47378 15.0129 9.64959 14.8371C9.82541 14.6613 10.0639 14.5625 10.3125 14.5625H19.6875C19.9361 14.5625 20.1746 14.6613 20.3504 14.8371C20.5262 15.0129 20.625 15.2514 20.625 15.5C20.625 15.7486 20.5262 15.9871 20.3504 16.1629C20.1746 16.3387 19.9361 16.4375 19.6875 16.4375Z"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"#301534"</span>/></span>
      <span class="hljs-tag"></<span class="hljs-name">svg</span>></span>
      <span class="hljs-tag"></<span class="hljs-name">summary</span>></span>
      <span class="hljs-tag"><<span class="hljs-name">p</span>></span>Frontend Mentor offers realistic coding challenges to help developers improve their frontend coding skills with projects in HTML, CSS, and JavaScript. It’s suitable for all levels and ideal for portfolio building.<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
    <span class="hljs-tag"></<span class="hljs-name">details</span>></span>
    

    In the code below, we customize the disclosure marker by hiding the default arrow and adding a custom icon to the right using the ::marker pseudo-element on <summary>. We also set its content as empty, which removes the marker altogether.

    <span class="hljs-comment">/* Styles for the clickable summary element*/</span>
    <span class="hljs-selector-tag">summary</span> {
      <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">700</span>;
      <span class="hljs-attribute">cursor</span>: pointer;
      <span class="hljs-attribute">display</span>: flex;
      <span class="hljs-attribute">align-items</span>: center;
      <span class="hljs-attribute">transition</span>: color <span class="hljs-number">0.2s</span> ease;
      <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1em</span>;
      <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.5em</span>;
    <span class="hljs-comment">/* Remove the default marker */</span>
      &::marker {
        <span class="hljs-attribute">content</span>: <span class="hljs-string">''</span>;
      }
    
      &<span class="hljs-selector-pseudo">:last-child</span> { 
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0</span>; 
      } 
    
      &<span class="hljs-selector-pseudo">:hover</span> { 
        <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--text-accent);
        <span class="hljs-attribute">outline</span>: none;
      }
    }
    
    <span class="hljs-selector-tag">p</span> {
      <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">1em</span>;
      <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--text-light);
    }
    <span class="hljs-comment">/* Styles for the collapsible <details> container */</span>
    <span class="hljs-selector-tag">details</span> {
      <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1em</span>;
    
      &:last-child { 
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0</span>; 
      }
    
      <span class="hljs-selector-class">.open-icon</span> {
        <span class="hljs-attribute">display</span>: none;
      }
    
      &<span class="hljs-selector-attr">[open]</span> {
        .open-icon {
          <span class="hljs-attribute">display</span>: inline;
        }
    
        <span class="hljs-selector-class">.closed-icon</span> {
          <span class="hljs-attribute">display</span>: none;
        }
      }
    
      <span class="hljs-selector-class">.open-icon</span>,
      <span class="hljs-selector-class">.closed-icon</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">1.8em</span>; 
        <span class="hljs-attribute">height</span>: <span class="hljs-number">1.8em</span>;
        <span class="hljs-attribute">flex-shrink</span>: <span class="hljs-number">0</span>;
      }
    }
    

    The GIF below shows the output of styling our accordion with the CSS code above.

    3d033ac2-e9d4-4836-8f3b-816513802353

    To have an FAQ question expanded when the page loads, add the open attribute to <details>. This is particularly useful for highlighting important information where the most crucial FAQ starts expanded.

    <span class="hljs-tag"><<span class="hljs-name">details</span> <span class="hljs-attr">open</span>></span>
        <span class="hljs-tag"><<span class="hljs-name">summary</span>></span>What is Frontend Mentor, and how will it help me?<span class="hljs-tag"></<span class="hljs-name">summary</span>></span>
    <span class="hljs-tag"></<span class="hljs-name">details</span>></span>
    

    Browser Support and Accessibility Considerations

    According to MDN, <details> is a well established feature that works across many devices and the popular browsers (Chrome, Edge, Firefox, and Safari) since January 2020.

    33407311-a4db-47ab-bc9f-16baaed5d060

    <details> includes built-in accessibility features that requires additional JavaScript in custom solutions such as keyboard navigation, screen reader support, and semantic structure. You can also add attributes like role, aria-expanded, and aria-labelledby to ensure even more accessibility.

    Conclusion

    <details> is a powerful yet under-utilized element for creating UI elements like accordions, FAQs, or navigation menus without JavaScript. It is easy to implement and lightweight, and yet improves user experience with interactive content.

    So, the next time you need to create any collapsible content, with accessibility and performance in mind, consider reaching for <details> and it will surely make your development life easier.

    Here are some helpful resources:

    • MDN Documentation for <details>

    • CSS-Tricks Guide to Styling Details

    • Web.dev Learn HTML: Details

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleExecute Ping Commands and Get Back Structured Data in PHP
    Next Article MIT Learn offers “a whole new front door to the Institute”

    Related Posts

    Development

    How to Fine-Tune Large Language Models

    September 5, 2025
    Artificial Intelligence

    Scaling Up Reinforcement Learning for Traffic Smoothing: A 100-AV Highway Deployment

    September 5, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-47281 – Kyverno JMESPath Variable Substitution Denial of Service

    Common Vulnerabilities and Exposures (CVEs)

    CodeSOD: All Locked Up

    News & Updates

    How Cybercriminals Crack Your Passwords (And How to Stay One Step Ahead)

    Development

    Changing the conversation in health care

    Artificial Intelligence

    Highlights

    I found a 36-in-1 multitool that absolutely belongs in your kitchen drawer – here’s why

    August 13, 2025

    This set by Kelvin Tools looks rather strange and bizarre, but it’s actually very effective.…

    TheMoon Malware Targets Aging Routers, FBI Issues Alert

    May 9, 2025

    Why Context Matters: Transforming AI Model Evaluation with Contextualized Queries

    July 27, 2025

    Sam Altman admits OpenAI “screwed up” GPT-5’s launch but shares a bold vision for the future — hints at “a cooler social experience with AI” and a potential Google Chrome buyout

    August 18, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.