Tutorials 23 min read

Fold a Section in a Note and the Fold May Not Be in the File — <details>, Foldable Callouts and Heading Folds, App by App

MMNMNOTE
markdownhtmldetails-elementgithubobsidiancalloutsreference

A Markdown note can fold a section three ways, and only one of them is written into the file in a form other apps read: a <details> HTML block. A foldable callout is Obsidian syntax that GitHub prints as text. A heading fold is an editor action with no syntax at all. Even <details> breaks between apps.

The question is old and steady. "Collapsible header in Markdown to html" has collected 54,238 views on Stack Overflow since July 2015 1. Seven questions on the same job — spoilers, expandable code, collapsible README headings — add up to 116,109 views 2.

One of those titles tells the whole story: a collapsible section that "renders markdown in GitHub repo but not on GitHub Pages" 2. Copy GitHub's recipe somewhere new and you may get literal **bold**, visible tags, or a fold that works in one app only.

Every result below was measured on 10 November 2026: nine cases through GitHub's Markdown API and six local settings of three CommonMark engines 3. Obsidian and VS Code were not run — their rows come from Obsidian's documentation and VS Code's source code, and are labelled that way.


The three folds, and which one is in the file

There are three ways to fold a section of a Markdown note. A <details> block is HTML written into the file. A foldable callout is written into the file too, but in Obsidian's dialect. A heading or list fold is a click in the editor, and nothing about it is written into the Markdown at all.

FoldWhat you typeWritten into the file?Where it folds
<details> block<details>, <summary>…</summary>, content, </details>Yes — as HTMLWherever the renderer allows raw HTML, GitHub included; where HTML is off, the tags print as text
Foldable callout> [!note]- or > [!note]+Yes — as Obsidian syntaxObsidian, per its docs; GitHub and plain CommonMark show an ordinary quote with the marker printed
Heading or list foldClick the arrow beside a headingNoOnly inside the editor that made it

Each fold fails differently — and the failure matters more than the success. A <details> block that meets an HTML-off renderer shows its tags. A callout that meets GitHub shows [!note]- as text. A heading fold that leaves its app simply disappears — the note opens unfolded.

Pick the failure you can live with.

Fold one: <details>, the fold that lives in the file

The <details> element is the only fold that is plain, standard HTML inside the note. GitHub documents it as the way to collapse a section of Markdown, and the HTML standard defines what it does. It folds wherever raw HTML reaches the page — but whether the Markdown inside it renders depends on blank lines.

GitHub's documentation opens with it: "You can streamline your Markdown by creating a collapsed section with the <details> tag." 4 It adds that "Any Markdown within the <details> block will be collapsed until the reader clicks" the triangle, and: "Within the <details> block, use the <summary> tag to let readers know what is inside." 4

The element itself is not a Markdown invention — the WHATWG HTML standard defines it: "The details element represents a disclosure widget from which the user can obtain additional information or controls." 5 Its default is closed — "If the attribute is absent, only the summary is to be shown," says the standard of the open attribute 5.

GitHub's own example has a particular shape. There is a blank line after <details>, another after the <summary> line, blank lines between the blocks inside, and one before </details> 4. Reduced to its bones, it looks like this:

<details>

<summary>Notes</summary>

**bold**

- one

</details>

That is the shape people copy from GitHub's page. It is also the one with the most to say about where it works.

Why GitHub's recipe needs its blank lines

In CommonMark, <details> and <summary> start a raw HTML block, and a blank line is what ends it. Everything before the first blank line passes through unparsed; Markdown resumes only after it. Leave the blank lines out and the bold stays as asterisks — on GitHub too.

The mechanism is the same one that decides whether Markdown survives inside a centered <div>, and it is laid out in full in our guide to aligning text in Markdown. The part that matters here is the list. CommonMark 0.31.2 starts this kind of HTML block when a "line begins with the string < or </ followed by one of the strings (case-insensitive)" on a list of 62 tag names 6. Both details and summary are on it.

So the receipt splits cleanly. With no blank lines inside, **bold** and - one stayed literal text in all five HTML-on settings, GitHub included — the section folded, but its contents arrived as raw asterisks and hyphens 3. With GitHub's blank lines, the same five settings rendered <strong> and a real list inside the fold 3.

Five for five, both ways.

This is the shape that stayed literal everywhere — the same content as GitHub's recipe, with the blank lines taken out:

<details>
<summary>Notes</summary>
**bold**
- one
</details>

Obsidian's help documents the opposite shape

Obsidian's help page on HTML makes two rules, and GitHub's recipe breaks both. Markdown inside HTML is not rendered, by design. And an HTML block "cannot contain blank lines" — which is precisely what GitHub's example is built from. Obsidian was not run for this piece; this is what its documentation says.

The first rule is stated flatly: "Obsidian does not render Markdown syntax inside HTML elements." 7 It comes with a reason: "This is an intentional design choice for performance optimization and to keep parser complexity low when managing large documents." 7

The second rule sits under the heading "HTML blocks must be self-contained": "HTML blocks must be complete and cannot contain blank lines within them. Blank lines will break the HTML block." 7 The page even explains why Markdown occasionally seems to work inside inline tags: "The Markdown is being processed outside of the HTML context." 7

Neither app is wrong. GitHub follows the CommonMark rule — the blank line hands control back to Markdown. Obsidian chose a simpler rule and says why — performance, and lower parser complexity on large documents. Each documented recipe is correct for its own renderer.

The trouble is the note that travels between them. On a reading of Obsidian's documentation, GitHub's recipe is exactly the shape that page says will break — and notes rarely stay in one app forever.

Where HTML is switched off, the tags become text

Some renderers do not pass raw HTML at all. They escape it, so <details> arrives on the page as visible characters and nothing folds. Both html-off defaults tested here did this for every <details> case. It is a deliberate safety setting — not a bug.

The two settings were markdown-it 15.0.3 with its default options and micromark 4.0.3 with GitHub-flavoured extensions and its defaults. Both printed &lt;details&gt; — the tag as text — in every <details> case 3. GitHub's blank-line recipe fared slightly better there: the Markdown between the escaped tags rendered as ordinary paragraphs and a list, unfolded 3.

The no-blank-line case was worse in markdown-it's default mode. The list item swallowed the closing tag, producing <li>one\n&lt;/details&gt;</li> — a bullet that ends with the literal text </details> 3.

The lesson is not to avoid <details>. It is to write the content inside it so that it still reads well when every fold is open and every tag is showing.

The recipe that holds in both: HTML all the way down

The one <details> shape that satisfies GitHub's renderer and Obsidian's documented rules at once uses no blank lines and no Markdown inside the block. Write the summary and the content in plain HTML. It folded and rendered in all five HTML-on settings tested, and it meets Obsidian's rules by construction.

The exact block below was re-run on GitHub and the three HTML-on engines, with the same result 3:

<details>
<summary><strong>Meeting notes</strong> — 10 November</summary>
<p>Decided to keep the draft in one file.</p>
<ul><li>Owner: the editor</li><li>Due: Friday</li></ul>
</details>

Why each choice is there:

The trade-off is plain — you write HTML instead of Markdown for that section. For a short fold, such as a spoiler or a long log, that cost is small.

When the destination is GitHub alone and you want Markdown inside — a code block, a heading, a long list — use GitHub's blank-line recipe instead. A fenced code block is the common case. With a blank line after </summary> and before </details>, GitHub highlighted the code inside the fold; with no blank lines, the backticks printed as text 3. The shape that worked:

<details>
<summary>Code</summary>

```js
const a = 1;
```

</details>

Three attributes worth knowing

Two small attributes change how a <details> block behaves, and both are in the HTML standard rather than in Markdown. open makes a section start expanded. name groups sections so only one stays open. A third detail — what GitHub does to those attributes — decides whether they survive.

Both attributes, written in the all-HTML style so the block also meets Obsidian's documented rules. GitHub returned open="" and name="user-content-faq" for this block; the three HTML-on engines passed it through unchanged 3:

<details open>
<summary>Starts expanded</summary>
<p>Shown when the page loads.</p>
</details>
<details name="faq">
<summary>First question</summary>
<p>First answer.</p>
</details>
<details name="faq">
<summary>Second question</summary>
<p>Second answer.</p>
</details>

Fold two: the foldable callout, which is Obsidian syntax

A foldable callout is a blockquote with a bracketed type and a + or - after it. Obsidian folds it. GitHub does not: its alerts accept no fold suffix, and adding one turns the alert back into an ordinary quote with the marker printed. The fold is in the file, but only Obsidian reads it.

Obsidian's help is short and clear: "You can make a callout foldable by adding a plus (+) or a minus (-) directly after the type identifier." 8 Then: "A plus sign expands the callout by default, and a minus sign collapses it instead." 8

> [!warning]- Collapsed by default
> hidden text

The syntax looks like GitHub's alerts, and the resemblance is real: our Markdown cheat sheet describes callouts as an Obsidian extension on the GitHub alert pattern, and uses the line above as its example. GitHub's documentation describes alerts as "a special blockquote line specifying the alert type, followed by the alert information in a standard blockquote," and lists five types 9. A fold suffix is not among the things it describes.

So the line was sent to GitHub as written, next to the same alert without the suffix — the two differ by one character:

> [!warning]
> shown text

> [!warning]- Collapsed by default
> hidden text

Without the suffix, > [!warning] became a styled warning alert. With it, > [!warning]- Collapsed by default came back as a plain <blockquote> with [!warning]- Collapsed by default printed as its first line 3. > [!NOTE]- behaved the same way 3. As configured here, commonmark.js, markdown-it and micromark have no alert syntax, so they printed the marker in every callout case 3.

There is one comfort in this failure — nothing is hidden, and nothing is lost. A reader on GitHub sees the warning text in a quote, with a line of bracket noise above it — the content survives even though the fold does not.

Fold three: the heading fold, which is not in the file at all

Folding a heading or a list in Obsidian is a click in the editor, not syntax in the note. Since no Markdown exists for "this section is folded," nothing in the file can record it. Obsidian's help does not say where it keeps fold state; one user reported in 2023 that it sits in the app's local storage.

Obsidian's help describes the action: "You can fold headings and indented lists by hovering the mouse cursor over the section you want to fold, and then selecting the arrow on the left." 10 The page covers commands, hotkeys and the settings that turn folding off. It does not say where the folded state is stored.

A 2023 forum thread asked exactly that. Its author noticed the folds survived restarts, "But unlike other state changes, I can find no evidence of any notes or configuration files changing." 11 A forum member replied: "After some inspection in the developer console, I found that information is stored in localStorage," keyed by the note's path 11. That is one user's inspection — not documented behaviour — and the app may have changed since.

The practical point holds either way — the fold is not in the Markdown, so it cannot travel with it. Open the same note on GitHub, in another editor, or on a second device without that app's local state, and every heading arrives unfolded.

For your own reading, that is often fine. A heading fold is a view, like a scroll position — useful in the moment, and not meant to be part of the document.

Which fold survives where: the matrix

This table shows what nine test cases did in seven renderer settings on 10 November 2026. Read a column to see one recipe's fate; read a row to see one destination's rules. Obsidian and VS Code are labelled by source, because neither was run.

Setting<details>, no blank linesGitHub's blank-line recipeAll-HTML recipe<details open>Markdown in <summary>Foldable callout > [!x]-Plain alert > [!x]
GitHub Markdown API (gfm)Folds; inner Markdown literalFolds; Markdown renderedFolds; renderedKept as open=""LiteralPlain quote, marker printedStyled alert
commonmark.js 0.31.2Folds; inner Markdown literalFolds; Markdown renderedFolds; renderedKeptLiteralQuote, marker printedQuote, marker printed
markdown-it 15.0.3, html: trueFolds; inner Markdown literalFolds; Markdown renderedFolds; renderedKeptLiteralQuote, marker printedQuote, marker printed
micromark 4.0.3 + GFM, HTML allowedFolds; inner Markdown literalFolds; Markdown renderedFolds; renderedKeptLiteralQuote, marker printedQuote, marker printed
markdown-it 15.0.3, defaultTags as text; list swallows </details>Tags as text; Markdown as paragraphsAll tags as textTags as textTags as text; the bold rendersQuote, marker printedQuote, marker printed
micromark 4.0.3 + GFM, defaultTags as textTags as text; Markdown as paragraphsAll tags as textTags as textTags as textQuote, marker printedQuote, marker printed
VS Code preview (from source, not run)Expected: as html: true rowExpected: renderedExpected: rendered————
Obsidian reading view (per docs, not run)Docs: no Markdown inside HTMLDocs: blank lines break the blockDocs-compliant——FoldsCallout

The markdown-it 14.3.3 release, published the same day as 15.0.3, gave identical output on all nine cases 3. The VS Code row is an inference: its built-in Markdown preview passes html: true to markdown-it in its source 12, so it should behave like that row. Neither assumption replaces a test in the app you use.

How to check your own destination

Two pastes tell you almost everything about a new destination: the all-HTML recipe, then GitHub's blank-line recipe. The first shows whether raw HTML is allowed at all. The second shows whether Markdown resumes after a blank line inside HTML. Together they place any app in a row of the matrix above.

  1. Paste the all-HTML recipe. If you see the tags, HTML is off and no <details> will fold there. If it folds, HTML is on.
  2. Paste GitHub's blank-line recipe. If the bold renders inside the fold, the app follows CommonMark's blank-line rule. If the asterisks print, or the block breaks apart, it does not.
  3. Try one callout with a -. If it folds, you are in an app that reads Obsidian's syntax. If [!note]- prints, you are not.
  4. Close the app and reopen the file elsewhere. Whatever is still folded is in the file. Whatever opened up was a view.

Static-site generators deserve a separate check, because they bring their own parser. kramdown, the default Markdown renderer for Jekyll 13, says of its default: "By default, kramdown parses all block HTML tags and all XML tags as raw HTML blocks." 14 Its parse_block_html option is off — "Since this is not wanted normally, the default is false." 15

Instead, it lets you switch parsing on per tag with a markdown attribute, such as markdown="1" or markdown="block" 14. kramdown was not run here; this is what its documentation says.

Hugo and other generators were not tested either. Run the two pastes there before trusting any recipe — including the ones above.

Frequently asked questions

The six questions below are Stack Overflow titles, kept in their askers' own words, and together they hold most of the 116,109 views counted above. Each answer is short and points back to the recipe or the matrix row that settles it, with untested apps named as untested.

Collapsible header in Markdown to html

Markdown has no syntax for a collapsible section, so use HTML: a <details> element with a <summary> line as its visible label. GitHub documents this recipe. It folds wherever raw HTML is allowed. For Markdown inside, add blank lines after </summary> and before </details>; for Obsidian, whose docs say Markdown inside HTML is not rendered, write the inside as plain HTML.

Code block in spoiler with markdown

Put the fence on its own lines inside <details>, with a blank line after the <summary> line and a blank line before </details>. On GitHub that rendered a highlighted code block inside the fold. Without the blank lines, the backticks printed as text. Never put the fence on the summary line.

Show dropdown area / expandable area with code in markdown file

The dropdown is a <details> element; the visible label is its <summary>. Code inside needs GitHub's blank-line recipe to render as a code block. Whether any of it folds depends on the destination allowing raw HTML, so paste the recipe there first and check that the tags are not printed as text.

Add collapsible section in hugo

Hugo was not tested for this piece, so no Hugo-specific claim is made here. The same two checks apply: paste the all-HTML <details> recipe to learn whether raw HTML reaches the page, then paste GitHub's blank-line recipe to learn whether Markdown renders inside it. The result places Hugo's setup in one matrix row.

How to make heading collapsible in Readme markdown file for GitHub?

GitHub cannot fold a Markdown heading by itself. Put the heading inside a <details> block instead, after a blank line: GitHub's own example does exactly this with "### You can add a header" placed below the summary. The summary is the always-visible label; the heading and everything after it fold away.

Content of collapsible sections (<details><summary>...) renders markdown in GitHub repo but not on GitHub Pages

GitHub's repository view and a Jekyll site can use different parsers. kramdown, Jekyll's default Markdown renderer, documents that it treats block HTML as raw by default, with its parse_block_html option off. Its docs offer a per-tag markdown attribute, such as markdown="1", to turn parsing on. Check your site's processor first.


A fold is a decision about what a reader sees first. Make it in the file, in plain HTML, or accept that it stays behind in the app that made it.


When your notes live as open Markdown files on your own device, the folds you write into them travel with the files — mnmnote.com is a local-first Markdown editor built around keeping notes that way.


References


Footnotes

  1. Stack Overflow Q31562552, "Collapsible header in Markdown to html": 54,238 views, asked 2015-07-22. Stack Exchange API 2.3 (accessed 2026-11-10). https://stackoverflow.com/q/31562552 ↩

  2. Stack Exchange API 2.3, questions 31562552, 32181339, 47392245, 71691219, 64237860, 52944720 and 67495928: 116,109 views combined (accessed 2026-11-10). https://api.stackexchange.com/2.3/questions/31562552;32181339;47392245;71691219;64237860;52944720;67495928?site=stackoverflow ↩ ↩2

  3. Own measurement, 10 November 2026. Nine Markdown cases rendered through GitHub's POST /markdown API (mode gfm) and six local settings: commonmark.js 0.31.2; markdown-it 15.0.3 (default and html: true) and 14.3.3 (html: true, identical output); micromark 4.0.3 with micromark-extension-gfm 3.0.0 (default and HTML allowed). Additional cases: the all-HTML recipe as printed, a fenced code block inside <details> with and without blank lines, and <details name="faq">. Endpoint documented at https://docs.github.com/en/rest/markdown/markdown#render-a-markdown-document ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17

  4. GitHub Docs. "Organizing information with collapsed sections." https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections (accessed 2026-11-10). ↩ ↩2 ↩3 ↩4

  5. WHATWG. HTML Living Standard, §4.11.1 "The details element" (last updated 9 November 2026). https://html.spec.whatwg.org/multipage/interactive-elements.html#the-details-element (accessed 2026-11-10). ↩ ↩2 ↩3 ↩4

  6. MacFarlane, J. (ed.). CommonMark Spec 0.31.2, §4.6 HTML blocks (2024-01-28). https://spec.commonmark.org/0.31.2/#html-blocks (accessed 2026-11-10). ↩

  7. Obsidian Help. "HTML content." https://obsidian.md/help/html (accessed 2026-11-10). ↩ ↩2 ↩3 ↩4 ↩5

  8. Obsidian Help. "Callouts" › Foldable callouts. https://obsidian.md/help/callouts (accessed 2026-11-10). ↩ ↩2

  9. GitHub Docs. "Basic writing and formatting syntax" › Alerts. https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax (accessed 2026-11-10). ↩

  10. Obsidian Help. "Folding." https://obsidian.md/help/folding (accessed 2026-11-10). ↩

  11. Obsidian Forum. "How does obsidian remember folded bullets" — opening post by zulutime and reply by ush, both 2023-10-14. https://forum.obsidian.md/t/how-does-obsidian-remember-folded-bullets/69343 (accessed 2026-11-10). ↩ ↩2

  12. microsoft/vscode. extensions/markdown-language-features/src/markdownEngine.ts at commit 3879d0e80f, line 401. https://github.com/microsoft/vscode/blob/3879d0e80f/extensions/markdown-language-features/src/markdownEngine.ts#L401 (accessed 2026-11-10). ↩

  13. Jekyll documentation. "Markdown Options." https://jekyllrb.com/docs/configuration/markdown/ (accessed 2026-11-10). ↩

  14. kramdown documentation. Syntax › HTML Blocks. https://kramdown.gettalong.org/syntax.html (accessed 2026-11-10). ↩ ↩2

  15. kramdown documentation. Options › parse_block_html. https://kramdown.gettalong.org/options.html (accessed 2026-11-10). ↩