markdown13 min read

Markdown Indent: The Complete Guide (2026)

Every way to indent in markdown — nested lists, paragraphs, code blocks, MDX. Plus a platform-by-platform table of what actually renders.

TL;DR

Markdown doesn't have a real indent feature. The only place it natively respects whitespace is inside lists — two spaces for nested unordered, three for ordered. For paragraph indents, use   or a blockquote. For code inside a list item, indent four spaces past the bullet. Four spaces outside a list creates a code block by accident, which is the single most common gotcha.

The honest answer to "how do I indent in markdown" is that you usually can't. Markdown collapses leading whitespace at the start of a paragraph, treats four spaces as a code block, and only respects indentation inside list items. Everything else is a workaround using HTML entities, blockquotes, or raw HTML.

This guide covers every method that actually works, ranks them by platform support, and shows the five failure modes you'll hit in real docs.

Prefer video? NeuralNine's beginner crash course covers lists and indentation along with the rest of markdown:

Beginner markdown walkthrough covering lists and indentation (NeuralNine).

The short answer: markdown doesn't really indent#

Markdown was designed in 2004 to be a plain-text format that converts cleanly to HTML. HTML doesn't care about leading whitespace in source — it collapses it. Markdown inherited that behavior.

So when you type four tabs at the start of a paragraph and the rendered output looks identical to the unindented version, the parser is working as designed. The exception is inside lists, where indentation determines nesting depth and is part of the syntax itself.

That means "indent in markdown" really means one of four things:

  • Nest a list (use indentation as syntax)
  • Push text right visually (use   or HTML)
  • Quote a block (use > as a left-rail indent)
  • Indent code inside a list (use four spaces past the bullet)

Each has its own rules and its own breakage modes. Let's go through them.

Indent a nested list (the only indent markdown natively supports)#

Nested lists are the one case where markdown is unambiguous: the indent of the child item must align with the text of the parent, not the bullet.

For unordered lists, that's two spaces. For ordered lists, three (because 1. is three characters wide).

Start with a parent bullet

Write your top-level item with a single - or * :

Markdown
- Parent item

Indent the child by two spaces

The child bullet's - lines up with the parent's text, which is two spaces in:

Markdown
- Parent item
  - Child item

Go deeper by adding two more spaces per level

Each level adds another two spaces:

Markdown
- Level 1
  - Level 2
    - Level 3
      - Level 4

Mix ordered and unordered

Ordered items use three spaces of indent for their children because 1. is wider:

Markdown
1. First step
   - Sub-bullet under step 1
   - Another sub-bullet
2. Second step

The CommonMark spec on list items is the canonical source here, and GitHub Flavored Markdown spec follows it almost exactly.

Two spaces, not four

You'll see old tutorials say to use four spaces for nested lists. That works on most renderers, but four spaces is also the trigger for an indented code block. If you ever paste a list snippet outside its parent context, four-space children will render as code. Two spaces is safer.

What about tab characters?#

CommonMark treats a tab as equivalent to four spaces, but tabs are a trap. Most editors auto-convert tabs to spaces on save. Git diff settings, CI formatters, and copy-paste between apps all mangle tabs silently. Pick spaces and commit to them.

Indent a paragraph or block of text#

Markdown has no first-line indent and no left-margin indent for paragraphs. You have three real options, ranked by reliability.

Option 1: blockquote as a left-rail indent#

A > at the start of a line creates a blockquote, which most renderers style with a left margin and a vertical bar:

Markdown
Regular paragraph here.
 
> This paragraph is visually indented because it's a blockquote.
> Subsequent lines continue the same block.

It's not technically an indent — it's a quote. But it renders as indented text everywhere, including in plain-text terminals. If you want a deeper dive on the syntax, see the blockquote syntax guide.

Option 2: non-breaking space entities#

The   HTML entity (and friends like   for a wider em-space) push text right without triggering whitespace collapse:

Markdown
    This paragraph starts with four non-breaking spaces, simulating a first-line indent.

This works because markdown parsers pass HTML entities through to the output untouched. The browser then renders each   as a real space. MDN has the full reference on the non-breaking space entity and other character codes.

Notion and some hosted CMS pipelines strip HTML entities during import. Test before you commit a long doc to entity-based indents.

Option 3: raw HTML with inline CSS#

For MDX and most markdown flavors that allow raw HTML, you can use:

HTML
<p style="text-indent: 2em;">This paragraph has a real first-line indent via CSS.</p>

This is the cleanest semantically, but it's also the most likely to be stripped by sanitizers. GitHub allows it in READMEs. GitLab allows it. Notion does not. Reddit does not.

Indent code inside a list item#

This is the case that breaks the most docs. You want a code block that belongs to a list item, like step 3 in a tutorial. The rule: indent the code fence (or the indented code) to align with the parent item's text — typically four spaces in.

Markdown
1. Install the package.
2. Add the import.
 
    ```ts
    import { Dokly } from "dokly";
  1. Initialize the client.
Text
 
Note the four-space indent before the triple backticks. Without it, the code block escapes the list and breaks the numbering. Step 3 will render as "1." instead of "3." because the parser thinks the list ended.
 
<Callout type="warning" title="GitHub and Mintlify render this differently">
GitHub is strict about the four-space rule. Mintlify and some MDX renderers are forgiving and accept two spaces or even none — but if you ever move that content to GitHub, the numbering breaks. Always use four spaces past the bullet for code blocks inside lists.
</Callout>
 
For inline code inside a list item, no indent rule applies — just write your backticks normally:
 
```markdown
1. Run `npm install`.
2. Then run `npm run build`.

Indent across platforms: what renders where#

Not every indent trick survives every renderer. Here's the truth table for the most common platforms, based on testing each method against current versions as of April 2026.

MethodGitHubGitLabMDX / DoklyNotionObsidianReddit
Nested list (2-space)
Blockquote >
&nbsp; entities
Raw HTML <p style>⚠️
4-space code in list⚠️
Tab character indent⚠️⚠️⚠️⚠️

✅ = renders as expected · ⚠️ = works inconsistently · ❌ = stripped or broken

The two methods that work everywhere are nested lists and blockquotes. If you're writing a README that needs to render on GitHub, GitLab, npm, and crates.io simultaneously, stick to those. The same applies when you're writing READMEs that render everywhere.

Common indent breakages and how to fix them#

Five real failures you'll hit, in order of frequency.

1. Tabs converted to spaces (or vice versa)#

You wrote a nested list with tabs. Your editor saved spaces. Or you wrote spaces, your linter changed them to tabs, and CI flipped them again. The list flattens in the rendered output.

Fix: add .editorconfig to your repo with indent_style = space and indent_size = 2. Most editors respect it automatically.

2. Nested list flattening on paste#

You copied a list from Notion or Google Docs into a markdown file. The indentation looked right but used non-breaking spaces or different whitespace. The parser saw one flat list.

Fix: paste into a plain-text editor first, then re-indent manually with regular spaces.

3. Accidental code block from 4-space indent#

You wanted an indented paragraph. You used four spaces. Markdown turned it into a code block with a monospace font and a gray background.

Fix: use a blockquote (>) or &nbsp; entities instead. Or use three spaces if you only want a small visual indent and don't care about precise alignment.

4. MDX JSX parse errors from indented <#

In MDX, leading whitespace before a < character can confuse the parser, especially if the < is followed by a letter. The build fails with a cryptic syntax error.

Fix: keep JSX components flush-left. Don't indent <Callout> or <Card> opening tags inside lists. If you need them inside list items, use a fragment or restructure with the component on its own line.

Markdown
- A list item with a callout inside:
 
<Callout type="tip">This works because the callout is flush-left.</Callout>
 
- Next item

The MDX content syntax docs explain exactly how the parser interleaves markdown and JSX.

5. Table cell content won't indent#

Markdown table cells don't respect leading whitespace at all. You can't indent the contents of a cell with spaces.

Fix: use &nbsp; entities, or accept that table cells are single-line and put the indented content outside the table. Same advice applies to horizontal rule whitespace gotchas — markdown's whitespace rules are unforgiving for any block element that isn't a list.

When to stop indenting and use a real component#

Most of the time someone reaches for indent tricks, what they actually want is a different visual element: a callout box, a numbered step, a card, a code panel. Indent is a low-bandwidth proxy for structure.

If you're writing in MDX, use the right component:

  • For a "note" or "warning" indent → use a Callout
  • For a step-by-step list with code → use Steps
  • For a grid of options → use Cards
  • For a side panel of related info → use a Tab or Accordion

Compare these two ways to write the same content. With raw markdown indent tricks:

Markdown
**Tip:**
 
&nbsp;&nbsp;&nbsp;&nbsp;Use Cmd+K to jump to any page instantly.
&nbsp;&nbsp;&nbsp;&nbsp;This works on every page in your docs.

With a real component:

MDX
<Callout type="tip">
  Use **Cmd+K** to jump to any page instantly. This works on every page in your docs.
</Callout>

The component version renders consistently, survives platform migrations, and doesn't break if someone re-indents the file. See Dokly's MDX components reference for the full list.

This is why switching to a visual MDX editor eliminates most indent headaches — you don't write whitespace at all. You drop in a Callout, type your text, and the rendered output is identical across every device and viewport.

Frequently Asked Questions#

Why doesn't markdown indent when I press tab?#

Markdown collapses leading whitespace at the start of a paragraph. A tab or a few spaces at the start of a line either does nothing, gets stripped, or — if you use exactly four spaces — turns the line into a code block. The only place markdown natively respects indentation is inside lists. For everything else you need a blockquote, an HTML entity like &nbsp;, or a raw HTML tag.

How many spaces should I use to indent a nested list?#

Use two spaces for unordered lists and three spaces for ordered lists, measured from the start of the parent item's text — not from the bullet. CommonMark and GitHub Flavored Markdown both follow this rule. Four spaces also works on most renderers, but it can accidentally trigger a code block if you're not inside a list, so two is the safer default.

How do I indent the first line of a paragraph in markdown?#

Markdown has no native first-line indent. The two workarounds are inserting non-breaking spaces (&nbsp;&nbsp;&nbsp;&nbsp;) at the start of the paragraph, or wrapping the paragraph in a raw HTML element with inline CSS like <p style="text-indent: 2em;">. The HTML approach works on GitHub, GitLab, and MDX renderers but is stripped by most CMS pipelines and by Notion.

Why does my indented text turn into a code block?#

If you indent a line by four or more spaces and it's not inside a list, the markdown parser treats it as an indented code block. This is part of the CommonMark spec. To prevent it, either use fewer spaces, wrap the line in a blockquote with >, or use HTML entities (&nbsp;) which the parser doesn't count as leading whitespace.

Can I use tab characters to indent in markdown?#

Technically yes, but it's unreliable. CommonMark treats a tab as equivalent to four spaces, but editors, git diff settings, and CI pipelines often convert tabs to two spaces (or vice versa) without warning. Use explicit spaces — two for nested lists, HTML entities for paragraph indents — so what you write is what renders.

How does MDX handle indented content differently?#

MDX parses your file as both markdown and JSX, which means leading whitespace before a < character can confuse the parser. Indenting a line that starts with a JSX tag often produces a build error. Keep JSX components flush-left, and only indent content inside them when you're sure the renderer accepts it. In Dokly's visual MDX editor, indentation is handled by components like Steps and Callout, so you don't write whitespace at all.

Next steps#

If you're tired of fighting markdown whitespace and want a docs editor where Callouts, Steps, and Cards just work without indent gymnastics, try Dokly free. The visual MDX editor handles the rendering so you can focus on what the doc actually says.

Written by Gautam Sharma, Founder Dokly

Building Dokly — documentation that doesn't cost a fortune. AI-ready docs out of the box.

Follow on X →
Start for free

Ready to build better docs?

Start creating beautiful, AI-ready documentation with Dokly today. No git, no YAML, no friction.

Get started free