Skip to content
ViewMarkdown

Markdown tables

Tables are the piece of Markdown people get wrong most often, usually for one of four reasons. Here is the syntax, the alignment rules, and a checklist for when a table renders as a row of pipes.

Updated September 2026

The syntax, and the two rows you cannot skip

A Markdown table is three things: a header row, a divider row made of dashes, and one or more body rows. Cells are separated by pipe characters. The leading and trailing pipes on each line are optional but worth keeping — they make ragged rows obvious at a glance.

Both the header and the divider are mandatory. A table with no divider row is just a paragraph full of pipes, and a table with no header row does not parse at all. If you genuinely want a headerless table, the usual workaround is a header row of empty cells, which renders as a thin blank strip.

The divider needs at least three dashes per column in some parsers, so --- is the safe minimum.

You type

| Region | Units | Revenue |
| --- | --- | --- |
| North | 1,204 | £18,300 |
| South | 980 | £14,110 |

You get

Region Units Revenue
North 1,204 £18,300
South 980 £14,110

Alignment with colons

Colons in the divider row set each column's alignment, and nothing else does. A colon on the left of the dashes aligns left, a colon at both ends centres, a colon on the right aligns right. No colon means the renderer's default, which is left in practice.

Align numbers to the right and text to the left; a column of right-aligned figures is far easier to scan. Alignment applies to the whole column including the header cell, and there is no per-cell override — that is a genuine limitation, not a syntax you have not found yet.

You type

| Item | Qty | Unit price |
| :--- | :-: | ---: |
| Cable | 4 | 7.50 |
| Adapter | 12 | 21.00 |

You get

Item Qty Unit price
Cable 4 7.50
Adapter 12 21.00

Whitespace does not matter, and that is the point

The pipes do not need to line up. Columns are determined entirely by how many pipes separate the cells, so a table typed by hand in a hurry renders identically to one padded into a neat grid. Both tables below produce the same output.

Many editors have a "format table" command that pads the columns for you, and it is worth using — not because the renderer cares, but because a misaligned source table hides the one row that has a missing cell. If you would rather not hand-align anything, build the table in a grid with the table generator and copy the syntax out.

You type

| A | B |
| --- | --- |
| 1 | 2 |

|A|B|
|-|-|
|1|2|

You get

A B
1 2
A B
1 2

Formatting inside cells

Most inline syntax works inside a cell: bold, italic, strikethrough, inline code, links and images. Block-level syntax does not — you cannot put a heading, a bullet list, a block quote or a fenced code block inside a cell, because the cell ends at the next pipe or newline.

Inline code inside a cell is the usual reason people hit the pipe problem below, since shell commands are full of pipes. Links work exactly as they do elsewhere, and are a good way to keep a table narrow: put a short label in the cell and let the link carry the detail.

You type

| Flag | Meaning | Docs |
| :-- | :-- | :-- |
| `-v` | **Verbose** output | [read](https://example.com/v) |
| `-q` | ~~Quiet~~ (removed) | — |

You get

Flag Meaning Docs
-v Verbose output read
-q Quiet (removed)

Pipes, empty cells and ragged rows

A literal pipe inside a cell must be escaped with a backslash, \|, or it ends the cell early and pushes the rest of the row into the next column. This bites hardest when documenting shell commands. Escaping works even inside inline code, which is the one place a backslash normally has no effect.

An empty cell is fine: leave nothing between the pipes. A row with fewer cells than the header gets padded with blanks; a row with more has the extras silently dropped, which is why a table can quietly lose data. Count your pipes when a column looks wrong.

You type

| Command | Notes |
| :-- | :-- |
| `ls \| wc -l` | Counts files |
| `pwd` |  |

You get

Command Notes
ls | wc -l Counts files
pwd

What Markdown tables cannot do

There are no merged cells — no colspan, no rowspan. There are no multi-line cells: a cell is one line of text, so a paragraph with a line break inside it is not possible in standard syntax. There is no column width control, no cell background, no nested table, and no caption.

The workarounds, in order of how well they travel. Repeat the value down a column instead of merging, and rely on sorting for the visual grouping. Replace an intended line break with a separator such as a semicolon or a middle dot. Move genuinely long content out of the table into a section below, and link to it from the cell. On GitHub you can use a raw <br> inside a cell for a line break — but raw HTML is disabled in this viewer, so it would show as text here.

Why isn't my table rendering?

Work down this list; it is almost always one of these.

  • No blank line above the table. If a paragraph sits directly on top of the header row, the whole table is absorbed into that paragraph. This is the most common cause by far.
  • The divider row is missing or malformed. It needs dashes, and the same number of columns as the header.
  • The column counts disagree. Header, divider and body rows must all have the same number of cells.
  • An unescaped pipe inside a cell has split the row.
  • The renderer has no table support. Tables are a GitHub Flavored Markdown extension; they work here and on GitHub, but not in Slack, Discord, or a strict CommonMark parser.
  • The table is indented four spaces, which makes it a code block.

You type

Results below.

| Test | Status |
| :-- | :-- |
| Unit | Pass |

You get

Results below.

Test Status
Unit Pass

The blank line after "Results below." is what makes this parse as a table.

Taking a table into Word, Docs or a spreadsheet

A rendered table copies cleanly. Open the document in a viewer, select the rendered table rather than the source, and paste into Word or Google Docs — you get a real table object with the alignment preserved. Pasting the raw Markdown instead gives you a block of pipes.

For a whole document, Markdown to Word converts tables into native Word tables in a .docx file, which is the reliable route when the document has several of them. Going the other way, pasting a spreadsheet range into a Markdown file gives you tab-separated text, not a table; run it through the table generator to get the pipes.

Frequently asked questions

How do I make a table in Markdown?

Write a header row with pipes between the cells, a divider row of dashes underneath, then your data rows. Leave a blank line above the table if any text comes before it.

How do I centre a column in a Markdown table?

Put a colon at both ends of that column's dashes in the divider row. A colon only on the left aligns left, and one only on the right aligns the column right.

Can you merge cells in a Markdown table?

No. Markdown tables have no colspan or rowspan. Repeat the value in each row, or move the content below the table, or use an HTML table where the renderer allows raw HTML.

How do I put a pipe character in a table cell?

Put a backslash in front of it. This works inside inline code too, which matters when documenting shell commands that pipe output.

Why does my table show as plain text with pipes?

Usually a missing blank line above it, a missing divider row, or a renderer without table support. Slack, Discord and strict CommonMark parsers do not render tables.

Can a table cell span two lines?

Not in standard Markdown — a cell is a single line. On GitHub a raw br tag works; this viewer disables raw HTML, so use a separator character instead.

Build a table in a grid

Type into cells, set alignment, and copy the Markdown out.