Markdown List Syntax - Complete Guide
What Are Markdown Lists
Lists are one of the most common formatting tools when writing documents — whether you're listing key points, ordering steps, or building a to-do checklist, you need them. Markdown provides several list types: unordered lists (bullet lists), ordered lists (numbered lists), nested lists (sublists), and task lists (checklists).
This tutorial covers everything from basic syntax to nesting rules, indentation pitfalls, and cross-platform compatibility differences. The goal is to make this the only reference you need.
Unordered Lists (Bullet Lists)
An unordered list puts a bullet point in front of each item — some people call them "bullet points" or "bulleted lists."
The syntax is straightforward: start the line with -, *, or +, add a space, then write your content:
- Apple
- Banana
- OrangeRendered output:
- Apple
- Banana
- Orange
All three symbols work identically:
* Asterisks work
+ Plus signs too
- Dashes are fine as wellThat said, I recommend sticking with one symbol per document. Honestly, this is partly a personal preference thing, but mixing them looks messy, and some parsers will treat different symbols as separate list blocks, inserting extra spacing between them. My own habit is to always use - because it conflicts with the fewest other Markdown syntax elements (* can be confused with bold/italic formatting).
Ordered Lists (Numbered Lists)
Ordered lists put numbers in front of each item. They're great for steps, rankings, or anything with a clear sequence:
1. Open the editor
2. Create a new file
3. Start writingRendered output:
- Open the editor
- Create a new file
- Start writing
Here's a detail many people don't know: the numbers don't actually affect the final order. Markdown parsers number items based on their position in the list. So the following produces the exact same result:
1. Open the editor
1. Create a new file
1. Start writingThere's one exception though — the starting number matters. If you start with 3, the list begins numbering from 3:
3. Third step
4. Fourth step
5. Fifth stepThis behavior is clearly defined in the CommonMark specification, and major platforms like GitHub, Obsidian, and VS Code all follow this rule.
A practical tip: if you might need to insert or remove items later, writing all items as 1. saves you from renumbering everything.
By the way, the marker for ordered lists must use a period ., not a closing parenthesis ). Something like 1) isn't supported by all parsers, so avoid it.
Nested Lists (Sublists)
Nested lists are lists inside other lists, used to express hierarchical relationships. The way to create them is through indentation.
Indentation Rules
You can use spaces or tabs for indentation. The key points are:
- 2-4 spaces of indentation all work
- 1 tab equals 4 spaces
- The sublist marker must be indented at least 1 space more than the parent list's content
- Fruits
- Apple
- Fuji
- Granny Smith
- Banana
- Vegetables
- Cabbage
- RadishRendered output:
- Fruits
- Apple
- Fuji
- Granny Smith
- Banana
- Vegetables
- Cabbage
- Radish
2 Spaces vs 4 Spaces
There's a catch here. The CommonMark spec defines unordered sublists as items indented 1-3 spaces. But different platforms don't always behave identically:
| Indentation | GitHub | Obsidian | VS Code |
|---|---|---|---|
| 2 spaces | Renders correctly | Renders correctly | Renders correctly |
| 3 spaces | Renders correctly | Renders correctly | Renders correctly |
| 4 spaces | Renders correctly | Renders correctly | Renders correctly |
From my own testing, 2 spaces works across virtually all platforms, looks more compact, and is what GitHub's official docs recommend. I used to prefer 4 spaces, but when I collaborated on a project where everyone else used 2, the mixed indentation looked terrible, so I switched.
One thing to keep in mind: if you indent more than 4 spaces (relative to the outermost list marker), some parsers will treat it as a code block — that's why text suddenly appears in monospace when you nest too deep. People on Reddit have complained about this exact issue.
Mixed Ordered and Unordered Nesting
Ordered and unordered lists can be nested within each other:
1. Prepare ingredients
- 500g flour
- 3 eggs
- 250ml milk
2. Start cooking
1. Pour flour into a bowl
2. Crack in the eggs
3. Add milk and stir well
3. BakeThis kind of mixed nesting is especially useful for step-by-step instructions or technical documentation.
Task Lists (Checklists)
Task lists — sometimes called "to-do lists" or "checkbox lists" — are an extension of GitHub Flavored Markdown (GFM). Just add [ ] or [x] to a regular list item:
- [x] Complete requirements doc
- [x] Review code
- [ ] Deploy to staging
- [ ] Release to productionRendered output:
- [x] Complete requirements doc
- [x] Review code
- [ ] Deploy to staging
- [ ] Release to production
A few things to note:
[ ]contains a single space, meaning incomplete[x]contains a lowercasex, meaning complete (uppercaseXis also supported on most platforms)- Before the brackets is
-, the same marker as regular lists
Task lists are especially common in GitHub Issues and PRs — you can check and uncheck items directly in the Markdown, and GitHub updates the source file automatically. Obsidian and some other editors support this interaction too.
Keep in mind that task lists are a GFM extension and not supported by all Markdown parsers. The original Markdown spec doesn't include them, so older renderers may display them as plain text.
Embedding Other Elements in Lists
This is a feature many people don't know about, but it's quite useful. You can insert paragraphs, code blocks, blockquotes, and even images between list items — as long as the indentation is correct.
Adding Paragraphs in Lists
Leave a blank line under a list item, then indent to align with the text content:
- First point
This is a continuation of the first point, indented to align with the text.
- Second pointAdding Code Blocks in Lists
Embedding a code block in a list requires 4 spaces of indentation (relative to the marker) or 1 tab, plus the fence markers:
1. Install the dependency:
```bash
npm install markdown-it- Import the module
Adding Blockquotes in Lists
- An important fact
> This quote belongs to the same list item as the text above
- Another pointHonestly, this kind of nesting is easy to mess up in practice. My advice: if you're nesting more than two levels deep, consider using headings to separate content instead of forcing everything into a list.
Common Issues and Lessons Learned
Lists Getting Merged Unexpectedly
If you write two consecutive lists with nothing in between, some parsers will merge them into one. The fix is to add a non-list line between them (like a regular paragraph or an HTML comment <!-- -->):
- List A, item 1
- List A, item 2
<!-- -->
- List B, item 1
- List B, item 2Starting an Ordered List from a Non-1 Number
As mentioned earlier, the starting number is meaningful. When you want to start from a specific number, just write it. But not all renderers support non-1 starting numbers — some ignore it and start from 1 anyway.
Deep Nesting Turns into Code Blocks
I ran into this one myself. While writing a multi-level outline, I nested to the fourth level and noticed the text had suddenly switched to monospace. The cause was that the indentation exceeded 4 spaces (relative to the outermost marker), so the parser treated it as an indented code block. The solution is to reduce nesting levels or use HTML <ul> / <ol> tags for deep nesting.
Lettered or Roman Numeral Lists
Standard Markdown doesn't support a. b. c. or i. ii. iii. style ordered lists. If you need them, here are some options:
- Use HTML:
<ol type="a">generates lettered lists - Use Pandoc: it supports the
fancy_listsextension witha.,A.,i.,I.markers - On GitHub and most platforms, you're limited to plain numbers
Quick Reference Table
| List Type | Marker | Example | Use Case |
|---|---|---|---|
| Unordered | - / * / + | - Apple | Bullet points |
| Ordered | number. | 1. First step | Steps / rankings |
| Nested | Indent 2-4 spaces | - Sub-item | Hierarchy |
| Task | - [ ] / - [x] | - [x] Done | To-do checklist |
Cross-Platform Compatibility
| Feature | GitHub | Obsidian | VS Code | Typora |
|---|---|---|---|---|
-/*/+ markers | Supported | Supported | Supported | Supported |
| Auto-numbered ordered lists | Supported | Supported | Supported | Supported |
| Non-standard starting number | Supported | Supported | Supported | Supported |
| Nested lists (2 spaces) | Supported | Supported | Supported | Supported |
| Nested lists (4 spaces) | Supported | Supported | Supported | Supported |
| Task lists | Supported | Supported | Preview only | Supported |
| Code blocks inside lists | Supported | Supported | Supported | Supported |
| Lettered / Roman numeral lists | Not supported | Not supported | Not supported | Not supported |
References
- CommonMark Spec - Lists — Official CommonMark lists tutorial
- Markdown Guide - Basic Syntax — Markdown Guide list syntax reference
- GitHub Docs - Lists — GitHub official list syntax documentation
- jmmv.dev - Markdown Lists — Markdown list formatting best practices
- Markdown Guide - Task Lists — Markdown Guide task list extension syntax