Markdown Tables: Complete Syntax Guide with Examples (2025)
Everything you need to know about Markdown tables — syntax, alignment, escape sequences, GFM extensions, accessibility tips, and how to generate them faster.
Markdown tables look intimidating the first time you see them, but they're one of the most useful features GitHub Flavored Markdown (GFM) added. This guide covers everything — the syntax, alignment rules, escape sequences, accessibility, and the patterns the best teams use to keep tables maintainable.
By the end you'll know how to write tables that look great in GitHub, GitLab, Notion, Obsidian, and pretty much every modern Markdown renderer.
The simplest Markdown table
A Markdown table has three parts:
| Header 1 | Header 2 |
| -------- | -------- |
| Cell 1 | Cell 2 |
| Cell 3 | Cell 4 |
- Header row — the labels at the top.
- Separator row — three or more dashes per column.
- Body rows — your data, one row per line.
Pipes (|) separate the columns. The first and last pipes on each line are optional but make tables easier to read in source.
Want to skip the pipes and just build one visually? Try our Markdown table generator.
Column alignment
The separator row controls alignment:
| Marker | Meaning |
|---|---|
:--- | Left-align |
:---: | Center-align |
---: | Right-align |
--- | Default (left in most renderers) |
Example:
| Item | Price | In stock |
| :--------- | ----: | :------: |
| Coffee | $4.50 | ✅ |
| Croissant | $3.25 | ✅ |
| Avocado toast | $11.00 | ❌ |
Renders as:
| Item | Price | In stock |
|---|---|---|
| Coffee | $4.50 | ✅ |
| Croissant | $3.25 | ✅ |
| Avocado toast | $11.00 | ❌ |
A few rules to remember:
- The colon goes on the side you want text to align to.
- You need at least three dashes per column (more is fine, fewer is invalid in strict parsers).
- Alignment is column-wide — you can't change it per cell.
Escape sequences in cells
Pipes (|) inside a cell would break the row. You have two options:
- Escape with a backslash:
\|is rendered as a literal| - Use the HTML entity:
|
| Expression | Meaning |
| ---------------- | ---------------------- |
| `a \| b` | The pipe character `|` |
| `regex: foo\|bar`| Match `foo` or `bar` |
Backticks need escaping too — but only if they conflict with inline code. The most reliable pattern: wrap the code in double backticks:
| Snippet | Description |
| ------------------------ | ----------------------- |
| `` `let x = 1` `` | Variable declaration |
| ``console.log(`Hi ${name}`)`` | Template literal |
Multi-line cells
Native Markdown tables don't support line breaks inside a cell. You have three workarounds:
-
Use
<br>— works in nearly every renderer.| Step | Description | | ---- | ---------------------------------- | | 1 | Install dependencies<br>`npm install` | | 2 | Run the dev server<br>`npm run dev` | -
Put long content outside the table and reference it with a numbered list.
-
Use plain HTML —
<table>works fine inside Markdown if the renderer allows raw HTML.
Wide tables on mobile
Markdown tables don't scroll horizontally by default. If your table is wider than the screen, the renderer either wraps the cells (ugly) or cuts them off (worse). Three fixes:
-
Limit columns. If you have more than ~6 columns, ask whether your table is really showing one concept or two.
-
Shorten cell content. Use abbreviations, status emojis, or icons.
-
Wrap in HTML for scrolling. Many docs sites style
<div class="overflow-x-auto">around generated tables:<div style="overflow-x:auto"> | Column 1 | Column 2 | … | Column 12 | | -------- | -------- | - | --------- | </div>
Tables inside lists, blockquotes, and footnotes
Most renderers expect tables at the top level of the document. You can usually put them inside blockquotes (with each line prefixed by >), but lists are inconsistent. The safest rule of thumb:
- Top-level table: always works.
- Inside a blockquote: works in GitHub and most renderers.
- Inside a list item: works in GFM but fails in strict CommonMark — avoid if portability matters.
> A blockquote with a table:
>
> | Method | Status |
> | ------- | ------ |
> | GET | 200 |
> | POST | 201 |
Tables with images
Yes, you can put images in cells. Keep them small — most renderers won't resize them:
| Avatar | Name | Role |
| ------------------------------------- | ----- | ------- |
|  | Alice | Founder |
|  | Bob | Engineer |
For consistent sizing, use raw HTML inside the cell:
| <img src="/avatars/alice.png" width="32" height="32" alt="Alice"> | Alice |
Tables with code blocks
You can't put a fenced code block (```) inside a Markdown table cell — the table syntax stops at the next pipe. Use inline code instead, or move the code out and reference it:
| Command | Description |
| ------------------ | ---------------------------- |
| `npm install` | Install dependencies |
| `npm run dev` | Start the development server |
| `npm run build` | Build for production |
If you really need multi-line code in a table, consider this layout instead:
### Commands
#### Install
```bash
npm install
Develop
npm run dev
## Accessibility tips for Markdown tables
When Markdown renders to HTML, the parser converts the header row to `<th>` and body rows to `<td>`. Two things help screen readers and the rest of your audience:
- **Always include a header row.** Even when the table is a list of pairs, a header improves announce order in screen readers.
- **Keep tables narrow.** Wide tables can be unreadable on small screens. Mobile users represent ~60% of web traffic in 2025 — design for them first.
For really complex data, write semantic HTML directly and apply a `<caption>`:
```html
<table>
<caption>Quarterly revenue (USD, millions)</caption>
<thead>
<tr><th>Quarter</th><th>Revenue</th><th>YoY</th></tr>
</thead>
<tbody>
<tr><td>Q1</td><td>12.4</td><td>+18%</td></tr>
</tbody>
</table>
How different renderers interpret edge cases
Markdown tables look standardized, but renderers disagree on edge cases. Here's where we've seen differences:
| Behaviour | GFM (GitHub) | CommonMark | Notion | Obsidian | This Editor |
|---|---|---|---|---|---|
| Tables at top level | ✅ | ❌ | ✅ | ✅ | ✅ |
| Tables inside lists | ✅ | ❌ | ⚠️ | ✅ | ✅ |
Cell with <br> line break | ✅ | ⚠️ | ⚠️ | ✅ | ✅ |
Cell with escaped pipe | | ✅ | ❌ | ✅ | ✅ | ✅ |
| Cell with inline image | ✅ | ❌ | ❌ | ✅ | ✅ |
✅ supported · ⚠️ partial · ❌ not supported
When in doubt: stick to GFM. It's the most widely supported flavor.
Generating Markdown tables faster
Writing tables by hand is fine for 3×3 grids. For anything bigger, use a generator:
- Markdown Viewer's table generator — a free, visual, spreadsheet-style builder with alignment controls.
- VS Code Markdown All in One — type
|---|---|---|and it auto-completes. - TableConvert.com / TableGenerator.com — older tools, but they handle CSV → Markdown well.
- Pandoc — for converting Excel/CSV → Markdown in batch from the command line.
If you already have CSV data, this one-liner with csvkit works:
csvformat -T input.csv | column -t -s $'\t' | sed 's/^/| /;s/$/ |/;s/ /| /g'
Common Markdown table mistakes
1. Forgetting the separator row. A header without | --- | --- | underneath isn't a table — it's just two paragraphs that happen to contain pipes.
2. Inconsistent column counts. If your header has three columns, every body row needs three. Renderers won't add empty cells automatically.
3. Putting markdown lists inside cells. They render as plain text in most engines. Use HTML <ul> and <li> if you absolutely must.
4. Long cells with no abbreviation. A cell with 300 characters destroys readability. Trim it or move the detail to a footnote.
5. Trying to merge cells. Markdown tables don't support colspan or rowspan. If you need merged cells, render to HTML.
When to use a Markdown table at all
Tables are great for uniform, scannable data. They're a poor fit for:
- Long-form descriptions — use a definition list (
<dl>) or bulleted list. - Steps in a process — use a numbered list with prose underneath each step.
- Comparisons of more than ~5 items — your reader's eyes will get lost. Consider a chart.
A good test: "Could this be a bulleted list?" If yes, it probably should be. Lists scan faster and adapt better to mobile.
Try it in the editor
Open the Markdown editor and paste any table from this article — you'll see it render live on the right. If your existing tables are messy, hit Beautify in the sidebar to auto-align the pipes.
Related articles
- Markdown cheat sheet — every Markdown feature on a single page
- How to add images in Markdown — alt text, sizing, hosting
- Markdown syntax guide — CommonMark and GFM, end to end
Quick reference
| Header 1 | Header 2 | Header 3 |
| :------- | :------: | -------: |
| Left | Center | Right |
| Cell | Cell | Cell |
That's all you really need. The editor, the cheat sheet, and the table generator take care of the rest.
Written by Markdown Viewer Team. Found this useful? Try the editor →
Keep reading
Hand-picked articles related to this one.
A complete Markdown syntax guide. Covers CommonMark, GitHub Flavored Markdown extensions, and modern conventions for technical writing.
How to write Markdown code blocks — fenced and indented, with syntax highlighting, line numbers, inline code, escape sequences, and tips for technical writing.
Master Markdown links — basic syntax, internal anchors, reference-style links, automatic linking, link titles, opening in new tabs, and SEO best practices.