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
- Orange

Rendered output:

  • Apple
  • Banana
  • Orange

All three symbols work identically:

* Asterisks work
+ Plus signs too
- Dashes are fine as well

That 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 writing

Rendered output:

  1. Open the editor
  2. Create a new file
  3. 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 writing

There'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 step

This 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
  - Radish

Rendered 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:

IndentationGitHubObsidianVS Code
2 spacesRenders correctlyRenders correctlyRenders correctly
3 spacesRenders correctlyRenders correctlyRenders correctly
4 spacesRenders correctlyRenders correctlyRenders 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. Bake

This 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 production

Rendered 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 lowercase x, meaning complete (uppercase X is 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 point

Adding 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
  1. Import the module

Adding Blockquotes in Lists

- An important fact

  > This quote belongs to the same list item as the text above

- Another point

Honestly, 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 2

Starting 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_lists extension with a., A., i., I. markers
  • On GitHub and most platforms, you're limited to plain numbers

Quick Reference Table

List TypeMarkerExampleUse Case
Unordered- / * / +- AppleBullet points
Orderednumber.1. First stepSteps / rankings
NestedIndent 2-4 spaces- Sub-itemHierarchy
Task- [ ] / - [x]- [x] DoneTo-do checklist

Cross-Platform Compatibility

FeatureGitHubObsidianVS CodeTypora
-/*/+ markersSupportedSupportedSupportedSupported
Auto-numbered ordered listsSupportedSupportedSupportedSupported
Non-standard starting numberSupportedSupportedSupportedSupported
Nested lists (2 spaces)SupportedSupportedSupportedSupported
Nested lists (4 spaces)SupportedSupportedSupportedSupported
Task listsSupportedSupportedPreview onlySupported
Code blocks inside listsSupportedSupportedSupportedSupported
Lettered / Roman numeral listsNot supportedNot supportedNot supportedNot supported

References

  1. CommonMark Spec - Lists — Official CommonMark lists tutorial
  2. Markdown Guide - Basic Syntax — Markdown Guide list syntax reference
  3. GitHub Docs - Lists — GitHub official list syntax documentation
  4. jmmv.dev - Markdown Lists — Markdown list formatting best practices
  5. Markdown Guide - Task Lists — Markdown Guide task list extension syntax