Markdown tables
Tables are one of the most useful parts of GitHub Flavored Markdown (GFM). They are also easy to break. This page covers the syntax, the alignment rules, and the limits you will run into.
Basic syntax
A table has three parts:
- A header row.
- A delimiter row made of dashes.
- Zero or more body rows.
Cells are separated by pipes (|).
| Fruit | Colour | Price |
| ------ | ------ | ----- |
| Apple | Red | 0.50 |
| Banana | Yellow | 0.25 |
Result:
| Fruit | Colour | Price |
|---|---|---|
| Apple | Red | 0.50 |
| Banana | Yellow | 0.25 |
The rules
- The header row and the delimiter row must have the same number of cells. If they do not, the text is not a table.
- Body rows can have fewer cells. The missing cells are left empty. Extra cells in a body row are ignored.
- The pipes at the start and end of each row are optional, but they make the source clearer.
- The table ends at the first blank line or at the start of another block, such as a heading or a blockquote. A plain line of text directly below the table becomes one more row, so leave a blank line after the table.
- To be safe, leave a blank line between a paragraph and the table below it.
Columns do not need to line up
Spaces around cell content are ignored. This compact version renders the same as a neatly aligned one.
Fruit|Price
-|-
Apple|0.50
Result:
| Fruit | Price |
|---|---|
| Apple | 0.50 |
Alignment
Add colons to the delimiter row to align a column:
:---aligns left.:---:centres.---:aligns right.
Without a colon the app’s default applies, which is usually left.
| Left | Centre | Right |
| :--- | :----: | ----: |
| a | b | 1.00 |
| aaa | bbb | 10.00 |
Result:
| Left | Centre | Right |
|---|---|---|
| a | b | 1.00 |
| aaa | bbb | 10.00 |
Right alignment is a good choice for numbers, so the decimal places line up.
Formatting inside cells
Cells take inline Markdown: emphasis, links, inline code and images.
| Element | Example |
| ------- | ------- |
| Bold | **yes** |
| Code | `npm i` |
| Link | [GFM spec](https://github.github.com/gfm/) |
Result:
| Element | Example |
|---|---|
| Bold | yes |
| Code | npm i |
| Link | GFM spec |
Block elements do not work in cells. You cannot put a list, a heading, a blockquote or a fenced code block in a table.
Escaping pipes
A pipe in cell text ends the cell. To show a literal pipe, escape it with a backslash. In GFM this also works inside inline code.
| Operator | Meaning |
| -------- | ------- |
| `a \|\| b` | logical or |
| x \| y | either |
Result:
| Operator | Meaning |
|---|---|
a || b |
logical or |
| x | y | either |
Line breaks in cells
Each table row must be one line in the source. A table cell cannot contain a real line break. Where the app allows raw HTML, use <br>.
| Step | Notes |
| ---- | ----- |
| 1 | Download<br>Install |
Result:
| Step | Notes |
|---|---|
| 1 | Download Install |
GitHub and GitLab accept <br> in table cells. Apps that strip raw HTML show the tag as text or drop it, so check your app.
No merged cells
GFM has no syntax for cells that span several columns or rows. There is no colspan or rowspan in Markdown. You have two options:
- Restructure the data, for example by repeating a value in each row.
- Write an HTML
<table>instead, if your app renders raw HTML.
An empty cell is not a merged cell. It is simply empty.
Where it works
Tables are not part of CommonMark. A strict CommonMark parser shows the pipes and dashes as plain text. Tables are defined in the GFM spec.
GitHub, GitLab and Obsidian render GFM tables. So does the built-in Markdown preview in VS Code. Most other Markdown apps support them too, but alignment, <br> and escaped pipes inside code are where they differ. If a table looks wrong, check your app’s documentation.
To read a table without counting pipes, Markko shows .md files formatted on a Mac and in Quick Look.
FAQ
Can I merge cells in a Markdown table?
No. GitHub Flavored Markdown has no syntax for merged cells (colspan or rowspan). If you need them, write an HTML table, in apps that allow raw HTML.
Do the columns have to line up in the source?
No. Aligning the pipes only makes the source easier to read. The renderer ignores extra spaces around cell content.
Can a table have no header row?
No. In GFM the header row and the delimiter row are required. If you do not want a header, some people leave the header cells empty, but how that looks depends on the app.
How do I put a list inside a table cell?
You cannot use block elements such as lists, code blocks or headings in a cell. Cells hold inline content only. Some apps that allow raw HTML let you fake a list with <br> and bullet characters.