Markdown Tables: Syntax, Alignment, and Generators
A complete guide to Markdown tables: GFM syntax, column alignment, escaping pipes, nested content, and when to reach for HTML instead. With copy-paste examples.
Markdown tables are one of the most-used and most-frustrating features in the format. They're great when the data is simple, painful when it isn't, and often a warning sign that you should be using a database, a spreadsheet, or raw HTML instead.
This guide covers the GitHub Flavored Markdown (GFM) table syntax completely: structure, alignment, escaping, multiline cells, nesting, and the limits you'll hit before you reach for HTML.
Basic syntax
A Markdown table is a header row, a separator row, and one or more data rows. Each row starts and ends with a pipe (|) and uses pipes to separate cells.
| Name | Role | Location | | -------- | ---------- | --------- | | Ada | Engineer | London | | Grace | Admiral | Arlington | | Katherine| Scientist | Hampton |
Renders as:
| Name | Role | Location |
|---|---|---|
| Ada | Engineer | London |
| Grace | Admiral | Arlington |
| Katherine | Scientist | Hampton |
The separator row (the second line) is what tells the parser this is a table. At minimum it needs three dashes between pipes: | --- | --- | --- |.
Column alignment
You control alignment with colons in the separator row:
| Left | Center | Right | | :-------- | :-------: | ------: | | apples | 2 | $1.50 | | bread | 1 | $4.25 | | eggs | 12 | $6.00 |
:---left-align (default):---:center---:right-align
Right-align numeric columns. Center headers. Left-align text. That's the rule — don't overthink it.
Inline formatting inside cells
Links, bold, italic, inline code, and images all work:
| Feature | Status | Docs | | --------------- | --------- | -------------------------- | | **Auth** | ✅ Shipped | [Guide](/docs/auth) | | *Billing* | 🟡 Beta | `/api/billing` | | ~~Legacy sync~~ | ❌ Removed | — |
Use emoji for status columns — they're universally supported and take less horizontal space than text like "In progress."
Escaping pipes
If a cell value contains a pipe, escape it with a backslash or use HTML entities:
| Operator | Meaning | | -------- | -------------------- | | `\|` | Pipe / bitwise OR | | `\|\|` | Logical OR | | `&` | Bitwise AND |
Inside inline code spans, pipes are already safe — `a | b` renders as a | b without escaping. That's the easiest fix when your cell contains code.
Multiline content inside cells
Markdown tables are strictly single-line per row. You cannot do this:
| Col | | --- | | Line 1 Line 2 |
The parser will break. Instead, use a <br> tag:
| Steps | | --------------------------------------------- | | 1. Clone repo<br>2. Run `npm install`<br>3. Start dev server |
For anything more complex — paragraphs, code blocks, lists — switch to raw HTML:
<table> <thead> <tr><th>Name</th><th>Description</th></tr> </thead> <tbody> <tr> <td>Setup</td> <td> <ol> <li>Clone the repo</li> <li>Install dependencies</li> <li>Run migrations</li> </ol> </td> </tr> </tbody> </table>
Most Markdown processors pass raw HTML through untouched. The cost: loss of Markdown's readability. The benefit: full control.
Empty cells
Leave the cell blank but keep the pipes:
| Name | Email | Phone | | ---- | -------------- | ---------- | | Ada | ada@example.io | | | Bob | | 555-0100 |
Don't use N/A or - unless the absence of data is itself meaningful. Blank is cleaner.
Minimum viable table
These all render correctly:
|a|b| |-|-| |1|2|
a|b -|- 1|2
The leading and trailing pipes are optional in GFM, though most style guides (and code formatters like Prettier) add them for consistency. Always use them — the visual bracketing helps humans read the source.
Column widths don't exist
There's no syntax for setting column width in Markdown tables. The rendered width is determined by content and the container's CSS. If you need fixed widths, use HTML with <col style="width: 20%"> or wrap the table in a div with a max-width and horizontal scroll.
When tables break down
Reach for alternatives when:
- The data has more than ~8 columns. Horizontal scroll is a UX problem on mobile. Consider a definition list (
<dl>) or a series of cards. - Rows need multi-paragraph content. Use an HTML table or a list of sections with headings.
- You need sorting, filtering, or pagination. That's a web app feature, not a document feature. Export the data as JSON/CSV and render it with a proper data grid.
- The table is really a form. Use HTML inputs.
- You have more than ~50 rows. Static tables that long are unreadable. Paginate, link to a separate page, or publish the raw CSV.
Tables in READMEs
Common README table patterns:
Feature comparison:
| Feature | Free | Pro | Enterprise | | ------------- | :--: | :-: | :--------: | | 5 projects | ✅ | ✅ | ✅ | | Unlimited | ❌ | ✅ | ✅ | | SSO | ❌ | ❌ | ✅ | | SLA | ❌ | ❌ | ✅ |
Environment variables:
| Variable | Required | Default | Description | | ------------- | :------: | ----------- | --------------------------- | | `PORT` | ❌ | `3000` | HTTP server port | | `DATABASE_URL`| ✅ | — | Postgres connection string | | `LOG_LEVEL` | ❌ | `info` | One of `debug`/`info`/`warn`|
Browser / platform support:
| Platform | Version | Supported | | -------- | ------- | :-------: | | Chrome | 120+ | ✅ | | Firefox | 120+ | ✅ | | Safari | 17+ | ✅ | | IE 11 | — | ❌ |
These three patterns cover 80% of README table use cases. Save them as snippets.
Generating tables from data
Writing tables by hand is tedious. A few automation paths:
- From a spreadsheet: copy cells and paste into the Markdown Table Generator or a dedicated conversion tool. Most accept tab-separated input.
- From CSV:
pandoc data.csv -t gfm -o out.mdhandles escaping and alignment. - From code/JSON: a small script using a library like
markdown-table(Node) ortabulate(Python) generates clean output. - From a database query: most CLI database clients (psql, mysql) have a Markdown or "pretty" output mode.
If you find yourself hand-editing a 20-row table, stop and script it.
Accessibility notes
- Always include a header row. Screen readers announce columns using header text.
- Keep cells short. Long cells are hard to scan with keyboard navigation.
- Don't use tables for layout. Tables are for tabular data. If you're using a table to arrange unrelated content side-by-side, use CSS Grid or Flexbox (via raw HTML) instead.
- Provide a caption or preceding heading. This gives the table semantic context. In raw HTML:
<caption>. In Markdown: a heading right above the table serves the same purpose.
Troubleshooting
"My table renders as plain text." The separator row is missing or malformed. You need at least three dashes per column and the separator must be on the line immediately after the header.
"Columns are misaligned in the rendered output." You have the wrong number of cells in a row. Count pipes — each row should have the same count as the header.
"A pipe inside my cell breaks the table."
Escape it with \| or wrap the value in backticks.
"The table is too wide and overflows." Markdown has no width controls. Wrap the rendered table in a scrolling container via CSS, or reduce columns, or switch to a different layout (list, cards).
"Alignment colons aren't working." Some older parsers (especially pre-GFM ones) ignore alignment. Confirm your renderer supports GFM tables.
Quick reference
| Left | Center | Right | | :---- | :----: | ----: | | a | b | c | | long | longer | 1,234 |
- Leading/trailing pipes: optional but recommended
- Separator row: required, at least 3 dashes per column
- Alignment:
:---left,:---:center,---:right - Escape pipes with
\|or wrap in backticks - Use
<br>for line breaks inside cells - Drop to raw HTML for complex content
Bookmark this page. Tables are the one Markdown feature you'll keep forgetting the fiddly details of — that's normal.
Frequently Asked Questions
Does standard Markdown support tables?+
How do I escape a pipe character inside a table cell?+
Can I put lists, code blocks, or images inside table cells?+
Why does my table look misaligned in the source but render fine?+
What's the easiest way to generate a Markdown table from a spreadsheet?+
Keep reading
The Complete Markdown Cheat Sheet (2026)
Every Markdown syntax you'll ever need, in one reference: headings, lists, tables, code blocks, links, images, task lists, and GitHub extensions. Print-friendly and bookmark-ready.
GitHub Flavored Markdown (GFM) Explained
What GitHub Flavored Markdown adds on top of standard Markdown: tables, task lists, autolinks, strikethrough, emoji, and platform-specific features. With examples you can use today.
Markdown vs. HTML: When to Use Which (2026)
A practical comparison of Markdown and HTML — performance, flexibility, portability, and when each is the right tool. With real examples and decision rules.