How to Create Collapsible Sections in Markdown
A markdown collapsible section uses the HTML details and summary tags. The syntax, the blank-line rule that breaks it, and where it does and doesn't work.
Short answer: There is no markdown collapsible section syntax in CommonMark or GFM. Use the HTML <details> and <summary> tags, which most markdown renderers pass through untouched. The critical detail: you must leave a blank line after the closing </summary> tag, or the markdown inside the collapsed block won't be parsed and will render as raw text.
Collapsible sections — disclosure widgets, expandable blocks, spoiler tags, whatever your team calls them — are one of the most requested things markdown can't do. Neither CommonMark nor GitHub Flavored Markdown defines any syntax for them. What exists instead is a native HTML element that markdown renderers happily let through, which works well once you know the two rules that make it fail.
The Basic Syntax
<details>
<summary>Click to expand</summary>
Hidden content goes here. It only appears when the reader clicks.
</details>
<details> is the container. <summary> is the always-visible label the reader clicks. Everything else inside <details> is hidden until they do. This is a native HTML element — no JavaScript, no CSS, no framework. The browser handles the toggle, the keyboard interaction, and the accessibility semantics.
If you omit <summary>, browsers fall back to a default label ("Details"). Always write one.
The Blank Line Rule
This is the gotcha that sends people to search engines. Compare:
<details>
<summary>Installation</summary>
1. Clone the repo
2. Run `npm install`
3. Run `npm test`
</details>
That renders as a single run-on line of literal text: "1. Clone the repo 2. Run npm install 3. Run npm test". The numbered list doesn't become a list. The backticks don't become code.
Now add a blank line after </summary>:
<details>
<summary>Installation</summary>
1. Clone the repo
2. Run `npm install`
3. Run `npm test`
</details>
Now the list renders as a list and the code spans render as code.
Why it happens: when a markdown parser hits a raw HTML block, it stops parsing markdown and copies the HTML through verbatim until it finds a blank line. The blank line is what tells the parser to switch back into markdown mode for the content that follows. The blank line before </details> closes the markdown region cleanly on the other end.
Some parsers are stricter still. Python-Markdown — used by MkDocs and many Python documentation toolchains — ignores markdown inside HTML blocks entirely unless you tag the element:
<details markdown="1">
<summary>Installation</summary>
1. Clone the repo
</details>
The markdown="1" attribute is a Python-Markdown extension. It's harmless on GitHub (the sanitizer strips unknown attributes), so including it is a reasonable hedge if you don't know where your document will be rendered.
Starting Expanded
Add the open attribute to have the section rendered already expanded:
<details open>
<summary>Read this first</summary>
Visible immediately, but the reader can collapse it.
</details>
open is a boolean attribute — its presence is what matters, and open="false" still means open. Remove the attribute to have the section start collapsed.
This is useful for a document where you want the first section expanded as a hint that the others can be expanded too. Readers frequently don't realize a collapsed block is clickable.
Nesting
You can nest <details> inside <details>, and the blank-line rule applies at every level:
<details>
<summary>Troubleshooting</summary>
<details>
<summary>Build fails on macOS</summary>
Check your Xcode command line tools are installed.
</details>
<details>
<summary>Build fails on Linux</summary>
Install the development headers for your distribution.
</details>
</details>
Two levels is usually the limit before it becomes hostile to read. If you're reaching for three, the document probably wants proper headings and a table of contents instead.
Where It Works
| Platform | <details> support |
|---|---|
| GitHub (READMEs, issues, PRs, wikis) | Yes |
| GitLab | Yes |
| Obsidian | Yes |
| Hugo, Jekyll, Astro, Eleventy | Yes (depends on the markdown parser's raw HTML setting) |
| MkDocs / Python-Markdown | Yes, with markdown="1" for inner markdown |
| Docusaurus / MDX | Yes |
| VS Code preview | Yes |
| No — HTML is stripped | |
| Discord | No — HTML is stripped |
| Slack | No — HTML is stripped |
| Notion | No — HTML is not accepted on paste |
| Quick Look plugins / static previews | Usually yes, since it's pure HTML |
The pattern is consistent: anywhere raw HTML passes through, <details> works, because it needs nothing beyond the browser. Anywhere HTML is stripped for safety — chat platforms, comment systems, forums — you get nothing, not even the summary text.
Some static site generators disable raw HTML in markdown by default for security. In Hugo that's markup.goldmark.renderer.unsafe, which must be set to true. If your <details> block is vanishing entirely rather than rendering as text, that setting is the usual cause.
OpenMark renders <details> blocks in Document view as working disclosure widgets you can click open and closed, which is the quickest way to check whether your blank lines are in the right place before you push a README.
What to Use It For
Long logs and stack traces in issues. A bug report with a 200-line stack trace is unreadable. Collapse the trace, keep the description visible.
FAQ sections. One <details> per question turns a wall of text into a scannable list of headlines.
Optional setup steps. Platform-specific instructions that only a third of readers need — collapse the two they don't.
Spoilers. The original reason many forums wanted this. <summary>Spoiler</summary> with the content hidden works, though note that it's obscured, not secured — the text is in the page source.
README sections below the fold. A full API reference collapsed under one summary keeps the README's first screen focused on what the project does.
Accessibility Notes
<details> is a real HTML element with real semantics, which puts it well ahead of a JavaScript accordion:
- The summary is focusable and toggles with Enter or Space. No
tabindexneeded. - Screen readers announce it as a disclosure widget and report its expanded or collapsed state.
- It works with JavaScript disabled and degrades to visible content in renderers that ignore the element.
Two things to watch. First, write summary text that describes the content — "Show more" tells a screen reader user nothing, while "Installation instructions for Linux" tells them everything. Second, collapsed content may not be reachable by the browser's in-page find, so don't hide anything a reader would reasonably expect to search for.
Don't put a heading inside <summary>. Nesting an <h2> inside a <summary> produces confusing semantics and inconsistent rendering. Style the summary with CSS instead, if the renderer allows it — GitHub does not, since it strips style attributes.
For other things markdown can't do natively, see subscript and superscript in markdown and how to add footnotes in markdown. If you're writing a project README, how to write a README.md and markdown for GitHub cover what else renders in that context.
Download OpenMark → — $9.99, one-time, native macOS. Write your README and see collapsible sections, tables, and diagrams render live before you commit.