tutorialguide12 min read

Markdown Tables: The Complete Syntax Guide (with Generator)

Pipes and dashes, mostly. But the details of alignment, escaping, and multi-line cells are where most writers slip — so here's all of it, in one document.

Mohammed AgratUpdated May 26, 2026

The smallest piece of markdown most writers get wrong. Three rows of pipes and dashes — that’s the language. Everything else is alignment, escaping, and knowing when to fall back to raw HTML.

TL;DR

  • A markdown table is built from pipes (|) and dashes (---). Three rows minimum: header, separator, data.
  • Tables are part of GitHub Flavored Markdown (GFM), not original markdown. Every modern tool supports them.
  • Use colons in the separator row to align columns: :--- left, :---: center, ---: right.
  • Escape literal pipes inside cells with \|.
  • For multi-line content, use <br> inside a cell — or drop in raw HTML for full control.
  • Building tables by hand is tedious. Use our live table generator or TablesGenerator.com to skip the typing.

Basic markdown table syntax

A markdown table needs three things: a header row, a separator row, and at least one data row. Each cell is bracketed by pipes. The separator row uses dashes (three or more) for each column.

| Name | Role        | Joined |
| ---- | ----------- | ------ |
| Ada  | Writer      | 1843   |
| Alan | Cryptanalyst | 1936  |
| Grace | Compiler dev | 1944 |

Renders as a three-column, three-row table with bold headers. The outer pipes are optional in most renderers (GitHub, mdclaudy, markdown-it), but including them makes the source file easier to read.

Cell widths in the source don’t affect the output. Pad with spaces for legibility in the raw .mdfile, or don’t — the renderer ignores whitespace inside cells. The following two tables produce identical HTML:

| Name | Role |
| ---- | ---- |
| Ada  | Writer |

|Name|Role|
|-|-|
|Ada|Writer|

Column alignment

Alignment is set in the separator row using colons. The dashes in between are decorative — three dashes is the minimum, but you can use as many as you like.

| Left | Center | Right |
| :--- | :----: | ----: |
| 100  |   200  |   300 |
| Cat  |   Dog  |   Owl |

The colons go in the separator row only. Putting them in the header or data rows does nothing. The three patterns:

  • :--- — left-aligned (the default)
  • :---: — center-aligned
  • ---: — right-aligned

Escaping pipes inside cells

The pipe character is special. To use it as literal content, escape it with a backslash:

| Operation | Symbol |
| --------- | ------ |
| Or        | \|     |
| And       | \&     |
| Xor       | ^      |

The alternative is the HTML entity &#124;, which every renderer also accepts. Backslash is shorter; entity is unambiguous. Use whichever you find more readable in your source files.

Inline formatting inside cells

Cells accept the full set of inline markdown: bold, italic, inline code, links, even inline images.

| Tool | Type | Site |
| ---- | ---- | ---- |
| **mdclaudy** | *editor* | [link](https://mdclaudy.com) |
| **Pandoc**   | *cli*    | `pandoc --version` |
| **markdown-it** | *lib* | npm package |

What you can’t put in a cell, without falling back to HTML: block-level markdown. No paragraphs, no lists, no code blocks, no headings. A cell is one line. For multi-line content, see the next section.

Multi-line cells

Standard GFM tables don’t support multi-line cells. The pragmatic workaround is <br> for line breaks:

| Step | What happens |
| ---- | ------------ |
| 1    | Read input<br>Parse markdown |
| 2    | Apply template<br>Subset fonts |
| 3    | Render PDF<br>Stream to client |

Renderers vary. Pandoc supports grid tablesfor genuine multi-line content (paragraphs, lists, code blocks inside cells), but grid tables aren’t valid GFM and won’t render on GitHub. Pick a flavor and stick with it.

GFM extensions and edge cases

GitHub Flavored Markdown added tables to the original Gruber spec in 2013. The behavior is now standard across every modern renderer — mdclaudy, Notion (as paste), Obsidian, VS Code, Mintlify, Docusaurus. A few corners worth knowing.

Empty cells

Leave a cell empty by putting nothing between the pipes: | | |. Most renderers display this as a blank cell. To force a visible empty cell when whitespace is being collapsed, use a non-breaking space: &nbsp;.

Column count must match

Every data row must have the same number of columns as the header. If you add an extra cell, most renderers silently drop it; some break. If you skip a cell, you get a blank. The fix is always to normalize the row count. Most editors highlight mismatches if you squint.

Tables don’t reflow on narrow screens

A wide markdown table on a phone is a wide markdown table on a phone — the renderer adds a horizontal scrollbar. There’s no native markdown idiom for responsive tables. If you need responsive behavior, drop down to HTML or render the table as a list on small screens via CSS.

Footnotes in cells

Footnote references work inside cells in any renderer that supports both footnotes and tables (Pandoc, mdclaudy, most static site generators). Syntax is the same as in body text:

| Claim | Evidence |
| ----- | -------- |
| Markdown won | Most-edited file type on GitHub[^1] |
| HTML predates it | Tim Berners-Lee, 1991[^2] |

[^1]: GitHub Octoverse 2023.
[^2]: World Wide Web announcement, August 1991.
Tables are the one piece of markdown where the source file becomes less readable than the rendered output. That’s why generators exist.

Table generators

Writing tables by hand gets tedious past about three rows. Two tools cover most cases.

TablesGenerator.com

TablesGenerator.comhas owned this corner of the internet for a decade. Spreadsheet-style cell editing, paste from Excel/CSV/HTML, output in markdown, LaTeX, HTML, plain text, MediaWiki. It’s ad-supported and dated-looking, but it works. For the common case — “I have a spreadsheet, I want a markdown table” — it’s still our recommendation when you’re in a hurry.

mdclaudy’s table generator

Our own live table generator was built for the writers who don’t want to bounce to an ad-laden tab. Type the table directly, paste TSV from Excel, or paste CSV. Live preview as you edit, alignment toggles per column, one-click copy. If you’re already writing in mdclaudy, the editor’s slash menu inserts tables natively — the generator is the no-signup browser tool for the one-off case.

Converting from Excel, Sheets, and CSV

Three approaches, ranked by effort.

Paste into a generator

Easiest. Copy your spreadsheet selection, paste into our generator or TablesGenerator. Both detect TSV (tab-separated values — the format Excel and Sheets use when you copy) and produce markdown.

Pandoc on the command line

If you have Pandoc installed (or are happy to brew install pandoc), the one-liner is:

pandoc input.csv -o output.md
pandoc input.xlsx -o output.md

Works on macOS, Linux, and Windows. Output is GFM by default. For a different flavor, add -t markdown_strict or -t commonmark.

Manual

For three rows or fewer, typing by hand is faster than opening a tool. Past three rows, you’re wasting your day.

When tables break in PDF or DOCX export

Markdown tables that look fine in the editor sometimes break when you export them. The three common failure modes:

  • Table wider than the page.Default renderers don’t auto-fit. Fix: shorter column content, smaller font in the table, landscape orientation, or split into two tables.
  • Cells with code blocks or images get truncated. GFM tables don’t officially support block content. Fix: flatten to text, or drop to raw HTML for the offending table.
  • Long rows wrap mid-cell awkwardly.The renderer doesn’t hyphenate. Fix: tighter content, or use a designed template (mdclaudy’s templates handle this; bare Pandoc doesn’t).

See our full guide on markdown-to-PDF formatting issues for the per-bug fixes.

Where markdown tables work (and don’t)

SurfaceTables supported?Notes
GitHubYes (GFM)The reference implementation.
mdclaudyYes (GFM)Slash menu inserts; PDF export styled per template.
ObsidianYesGFM-compatible; live preview.
VS Code previewYesWith the built-in markdown preview.
Notion (paste)YesConverts to native Notion table block.
Mintlify / DocusaurusYesGFM by default.
PandocYes — and grid tablesSupports more variants than GFM.
SlackNoPipes render as literal characters. Use a code block.
DiscordNoSame as Slack.
Reddit (new)Yes (GFM)The Fancy Pants editor supports tables.
WhatsAppNoNo markdown-table support; pipes render literally.
Original Gruber specNoTables were never in the original 2004 spec.

Falling back to raw HTML

When markdown can’t express what you need — merged cells (colspan / rowspan), captions, multi-line cells with paragraphs, custom CSS classes — you have one escape hatch: write a real HTML table. Every flavor of markdown passes inline HTML through to the renderer.

<table>
  <caption>Sales by region, Q1</caption>
  <thead>
    <tr><th>Region</th><th colspan="2">Quarter</th></tr>
    <tr><th></th><th>Q1</th><th>Q2</th></tr>
  </thead>
  <tbody>
    <tr><td>EMEA</td><td>120k</td><td>140k</td></tr>
    <tr><td>APAC</td><td>90k</td><td>110k</td></tr>
  </tbody>
</table>

Use the fallback sparingly. Once you’re writing HTML, the portability argument for markdown weakens, and the raw block won’t render on every surface (most notably, plain-text renderers and some chat platforms strip it).

Frequently asked questions

How do I make a markdown table?

Use pipes (|) to separate columns and dashes (---) on the second row to mark the header. Example: | Name | Role | on line one, | ---- | ---- | on line two, then | Ada | Writer | on line three. The renderer turns it into a real HTML table. Tables are a GitHub Flavored Markdown (GFM) extension, not the original Gruber spec, but every modern tool supports them.

What is the markdown table syntax?

Three rows minimum: a header row with column names, a separator row with dashes for each column (and optional colons for alignment), and one or more data rows. Each cell is wrapped in pipes. The outer pipes (at the start and end of each line) are optional but recommended for readability.

How do I align columns in a markdown table?

Use colons in the separator row. :--- is left-aligned ( the default), :---: is centered, and ---: is right-aligned. The colons go in the separator row only — not in the header or data rows.

How do I put a pipe character inside a cell?

Escape it with a backslash: \|. Without the escape, the renderer treats the pipe as a column separator and breaks the table. You can also use the HTML entity &#124; if you prefer.

Can markdown tables have multi-line cells?

Not in standard GFM tables — a cell must be one line. The standard workaround is to use <br>for line breaks inside a cell. If you need true multi-line cells (with paragraphs, lists, or code blocks), use Pandoc’s grid tables or pipe tables with HTML, or drop a raw <table> into your markdown.

How do I convert an Excel or Google Sheets table to markdown?

Three options. (1) Copy the cells, paste into a tool like TablesGenerator.com, then export to markdown. (2) Use our live table generator — it accepts TSV or CSV paste. (3) On the command line: pandoc input.csv -o output.md. All three produce GFM-compatible output.

Why does my markdown table break when I export to PDF?

Three usual causes: pipes weren’t escaped, the column count is inconsistent across rows, or the table is wider than the page. The first two are syntax bugs. The third is a layout problem — see our guide on markdown-to-PDF formatting issues for fixes.

Do markdown tables work in Notion, Slack, and Discord?

Notion: yes — paste a GFM table and it converts to a Notion table block. Slack: no — Slack’s mrkdwn flavor doesn’t support tables; the pipes show as literal characters. Workaround: use a code block. Discord: no — same as Slack; tables aren’t supported.

─── try mdclaudy ───

Write markdown. Ship a designed PDF.

Fifteen hand-built templates. Optional AI. Free up to 50 documents.

No card. 50 documents included.
─── Related reading