How to Make a Table in Markdown
Write a Markdown table with a header row and a separator row, align the columns, escape pipes, and fix a table that will not render. Plus task lists, strikethrough, code fences and autolinks.
To make a table in Markdown, write a header row, then a separator row of hyphens, then one line for each data row, with a pipe (|) between the columns. Paste it into the Markdown Live Preview to see the table rendered as you type.
| Name | Role | Team | | --- | --- | --- | | Ada | Engineer | Platform | | Grace | Reviewer | Docs |
That renders as a table with the headings Name, Role and Team and two rows:
| Name | Role | Team |
|---|---|---|
| Ada | Engineer | Platform |
| Grace | Reviewer | Docs |
Tables are part of GitHub Flavored Markdown (GFM). The sections below follow the GFM specification and check each rule in the preview.
What are the parts of a Markdown table?
A table is a single header row, a separator row (the spec calls it the delimiter row) and zero or more data rows. The separator row is what tells the renderer that the lines above and below it are a table.
- The pipes at the start and end are optional.
Name | Roleover--- | ---works, but the spec recommends the outer pipes for readability and to avoid ambiguity. - The pipes do not have to line up. Spaces between a pipe and the cell content are trimmed, so
|a|b|is the same as a padded row. - There is no table without a header row. If you do not want visible headings, leave the header cells empty:
| | |. - A header and separator with no rows is a valid table. It renders the headings and no body.
How do I align the columns?
Put a colon at the left end, the right end, or both ends of the hyphens in the separator row:
| Left | Center | Right | Default | | :--- | :---: | ---: | --- | | a | b | c | d |
| In the separator row | What the preview produces |
|---|---|
| :--- | Left: the cells get align="left" |
| :---: | Center: the cells get align="center" |
| ---: | Right: the cells get align="right" |
| --- | No alignment is set, so the default style applies |
The alignment applies to the heading and to every cell in that column, and it is kept when you use Copy HTML in the preview.
How do I put a pipe, a link, code or a line break in a cell?
A pipe
A pipe ends the cell, so write \| for one that belongs in the text. That includes a pipe inside inline code: without the backslash, `a | b` is cut into two cells and the backticks are shown as text; with it, the cell holds the code a | b.
| Expression | Meaning | | --- | --- | | a \| b | a or b | | `a \| b` | the same, as code |
Inline Markdown
Bold, italic, inline code, links, images and strikethrough all work in a cell:
| Item | Notes | | --- | --- | | **Bold** | *italic* and `code` | | [A link](https://example.com) | ~~old~~ |
A line break
A row has to stay on one line, so use an HTML <br> to break a line inside a cell: | first line<br>second line | x |. The preview keeps the <br> when it sanitizes the HTML.
What a cell cannot hold
The spec says that block-level elements cannot be inserted in a table. A list, a heading or a code block does not work inside a cell: a cell that starts with - item shows the text - item, not a list.
What if the rows do not have the same number of cells?
- A data row with fewer cells than the header gets empty cells added at the end.
- A data row with more cells has the extra cells ignored.
- The header and the separator row must have the same number of cells. If they differ, it is not a table at all, and the lines are shown as ordinary text.
Why is my Markdown table not showing up?
Check these, most common first:
- There is no separator row. Without the line of hyphens the rows are plain text. In the preview each line is shown with a line break, which looks like a column of pipes.
- The header and separator have a different number of columns.
| a | b |over| --- | --- | --- |is not a table. - The table is indented four spaces or more. That makes it an indented code block, and the pipes are shown as code.
- A pipe inside a cell is not escaped. It splits the cell. Write
\|, also inside inline code. - The next line after the table is not blank. A line right after the last row becomes another row, with the rest of its cells empty. The spec has this exact case. End the table with a blank line.
- A blank line in the middle of the table. The table ends at the first blank line, so rows after it are plain text and need their own header and separator.
- There is no blank line before the table. The preview still renders a table that directly follows a line of text, but the spec does not say what should happen, so leave a blank line before the table to be safe.
The Table button in the preview
The Table button in the toolbar inserts a starter table with two columns and one row at the cursor. It adds a blank line before the table and after it where one is missing, so the table stays a table and the text around it stays text. In an empty editor it inserts just the table.
Which other GitHub-flavored Markdown features do people use next?
Task lists
Start a list item with [ ] for an open task or [x] for a finished one. They are shown as checkboxes that cannot be clicked:
- [x] Write the header row - [ ] Add the separator row
Strikethrough
Wrap the text in two tildes, ~~like this~~. The spec also accepts one tilde, and three or more tildes do not make a strikethrough.
Fenced code blocks with a language
Put the code between lines of three backticks or three tildes, and the name of the language right after the opening fence. A JSON example, once you have formatted and validated it, goes in a block that starts with ```json.
The Markdown Live Preview highlights these languages. Names are not case sensitive, so JS works like js:
| Language | Names that work after the fence |
|---|---|
| Markup | markup, html, xml, svg, mathml |
| CSS | css |
| JavaScript | javascript, js |
| TypeScript | typescript, ts |
| JSON | json |
| Bash | bash, shell, sh |
Any other language, such as Python, YAML or SQL, is still shown in a code block, just without colors. The preview reads the first word after the opening backticks as the language name, so extra words there, as in ```ts title="a.ts", do not stop the highlighting.
Autolinks
A plain https://example.com becomes a link, and so does www.example.com (its link starts with http://) and an email address (its link starts with mailto:). A URL in angle brackets, <https://example.com>, is a link too.
What is different in the Markdown Live Preview?
- A single line break becomes a
<br>. The preview is set to turn every newline inside a paragraph into a line break. GitHub does the same in issues, pull requests, comments and discussions, but not in a.mdfile such as a README, where a single newline does not break the line. So text that looks right in the preview can run together in a README. To force a break in a.mdfile, end the line with two spaces or a backslash, or use<br>. - The HTML is sanitized. Scripts and inline event handlers such as
onerrorare removed before the preview is shown or the HTML is copied. - There is a toolbar. Bold, Italic, Code, Link, H2, Image, Table and Task add the syntax at the cursor or around the selected text.
- You can take the result with you. Copy HTML copies the sanitized HTML, Copy Markdown copies the source, and Download .md saves it. A switch changes the preview between light and dark, and the bar below shows the word, character and line counts and the reading time.
- Everything runs in your browser. Nothing you type is uploaded.
Try the Markdown Live Preview
Open the Markdown Live Preview, paste one of the tables above on the left, and watch it render on the right. It starts with a small table and a task list so you can see them straight away. Change a separator row to :---: to see a column centered, or add a stray pipe to see a cell split.
How to make a table in Markdown
1. Write the header row
Put the column names between pipes on one line, such as | Name | Role |. A table always has a header row; leave the cells empty if you do not want visible headings.
2. Add the separator row
On the next line, write one group of hyphens for each column, such as | --- | --- |. Use a colon at the left, right or both ends of a group to align that column left, right or center. The number of columns must match the header row.
3. Add one line for each data row
Write each row on its own line with a pipe between the cells. A row with fewer cells gets empty cells, and extra cells are ignored. The pipes do not have to line up.
4. Escape pipes and mark line breaks
Write \| for a pipe that belongs in a cell, including inside inline code, and use <br> for a line break inside a cell. Cells cannot hold lists, headings or code blocks.
5. Leave a blank line after the table and preview it
A non-blank line right after the last row becomes another row, so end the table with a blank line. Then check the result in the Markdown Live Preview.
// Frequently Asked Questions
Can a Markdown table have merged cells or column widths?
No. The GitHub Flavored Markdown table syntax has no way to merge cells or to set column widths. The Markdown Live Preview does render an HTML table that you write in your Markdown, after sanitizing it, but other sites may remove HTML, so check where the Markdown will be shown.
Do the pipes in a Markdown table have to line up?
No. The spaces between a pipe and the cell content are trimmed, so a table written as |a|b| works the same as a neatly padded one. Lining the pipes up only makes the source easier to read.
How do I make a Markdown table without a header?
You cannot leave the header row out, because a table is defined as a header row, a separator row and the data rows. Leave the header cells empty, as in | | |, and the table is rendered with an empty header.
Why does my table work in the preview but not on another site?
Tables are an extension in GitHub Flavored Markdown. Original Markdown and plain CommonMark have no table syntax, so a site needs GFM or its own table extension to render one. Check which flavor the site uses.
Is my Markdown uploaded when I use the preview?
No. Parsing, sanitizing, previewing and exporting all happen in your browser, and your document never leaves the tab.