Skip to main content

Markdown Tables

Pipe table syntax, column alignment, inline formatting, escaping pipes, line breaks in cells, and the mistakes that stop a table from rendering.

Tables are a GitHub Flavored Markdown extension, not part of CommonMark. They work on GitHub, GitLab, Obsidian, Reddit, and most static-site generators, but not in Discord or in Slack messages you type.

Short answer

Separate columns with pipes, and put a delimiter row of hyphens under the header: | Name | Role | then | --- | --- | then one line per row. Colons in the delimiter row set alignment: :--- left, :---: center, ---: right. Write a literal pipe as \|, and a line break in a cell as <br>. Rather not type pipes? Build it in the Markdown table generator.

Basic Syntax

A Markdown table needs a header row and, directly under it, a delimiter row of hyphens with one cell per column. Data rows are optional. The pipes at the start and end of each line are optional too, and the columns do not have to line up: the padding above is only there to make the source readable.

3-column table with a header and three data rows
| Name    | Role        | Location |
|---------|-------------|----------|
| Alice   | Developer   | NYC      |
| Bob     | Designer    | LA       |
| Charlie | PM          | London   |
Preview
Name Role Location
Alice Developer NYC
Bob Designer LA
Charlie PM London
How many hyphens? The GFM spec and GitHub's renderer accept a single hyphen per delimiter cell, but GitHub's own docs ask for three and Obsidian's ask for two. Use --- and the table works everywhere. The hyphen count does not set the column width.
Skip the pipes: the Markdown table generator builds the syntax from an editable grid, sets alignment per column, and converts rows pasted from Excel or Google Sheets.

Column Alignment

Add colons to the delimiter row to control alignment. The colon goes on the side you want the text flush against: :--- for left, :---: for center, ---: for right. To center the whole table rather than its text, see centering in Markdown.

Left & Right:--- left aligns. ---: right aligns. Colon goes on the side you want the text flush against.
| Item   | Price     |
|:-------|----------:|
| Coffee | $3.50     |
| Bagel  | $2.50     |
Preview
Item Price
Coffee $3.50
Bagel $2.50
Left, Center, RightThree columns with three different alignments. You can mix them in the same table.
| Feature | Status | Score |
|:--------|:------:|------:|
| Dark mode | Yes | 95 |
| SSO | No | 0 |
Preview
Feature Status Score
Dark mode Yes 95
SSO No 0

Inline Formatting in Cells

Inline Markdown (bold, italic, code, strikethrough, links) works inside table cells. Block-level syntax does not: a cell is a single line, so a list, heading, blockquote, or fenced code block inside one renders as literal text.

Bold, italic, code, and links in cells
| Style   | Syntax              | Result        |
|---------|---------------------|---------------|
| Bold    | `**bold**`          | **bold**      |
| Italic  | `*italic*`          | *italic*      |
| Code    | `` `code` ``        | `code`        |
| Link    | `[text](url)`       | [Docs](https://example.com) |
Preview
Style Syntax Result
Bold **bold** bold
Italic *italic* italic
Code `code` code
Link [text](url) Docs

Escaping Pipes

To put a literal pipe character in a cell, escape it with a backslash: \|. That includes pipes inside inline code. Cells are split on pipes before backticks are read, so wrapping text in backticks does not protect a pipe the way it protects asterisks. The backslash itself does not appear in the rendered table.

Escaped pipes in plain text and in inline code
| Command      | What it does               |
|--------------|----------------------------|
| `ls \| grep` | Filter a directory listing |
| a \|\| b     | Logical OR, as plain text  |
Preview
Command What it does
ls | grep Filter a directory listing
a || b Logical OR, as plain text

Line Breaks Inside Cells

Each table row has to fit on one line of source, so pressing Enter ends the row. To break a line inside a cell, insert an HTML <br> tag. For the other ways to break lines outside tables, see Markdown line breaks.

HTML line breaks in a table cell
| Column | Tall Column |
|--------|-------------|
| A      | Line 1<br>Line 2<br>Line 3 |
| B      | Single line |
Preview
Column Tall Column
A Line 1
Line 2
Line 3
B Single line
Heads up: <br> works on GitHub, GitLab, and in VS Code. In MDX, which Docusaurus uses for every file by default, write <br /> instead: a bare <br> fails the build with "Expected a closing tag".

Common Mistakes

Four mistakes cause nearly every broken table. Each row shows the broken version and the corrected one side by side.

Broken

| Name | Role |
| Alice | Developer |
| Bob | Designer |

Fixed

| Name  | Role      |
|-------|-----------|
| Alice | Developer |
| Bob   | Designer  |
The delimiter row (|---|---|) under the header is required. Without it there is no table, just a paragraph of text with pipes in it.

Broken

| Name | Role | Team |
|------|------|
| Alice | Dev | Core |

Fixed

| Name  | Role | Team |
|-------|------|------|
| Alice | Dev  | Core |
The delimiter row must have exactly as many cells as the header row, or the whole table renders as plain text. Body rows are forgiving: missing cells are left empty and extra cells are silently dropped.

Broken

| Command | Use |
|---------|-----|
| `ls | grep x` | Filter |

Fixed

| Command | Use |
|---------|-----|
| `ls \| grep x` | Filter |
Cells are split on pipes before backticks are read, so a | inside inline code still starts a new cell, and here the Filter text is dropped as an extra cell. Escape it as \| even inside backticks. The backslash does not appear in the output.

Broken

| Name  | Role |
|-------|------|
| Alice | Dev  |
This sentence was meant to follow the table.

Fixed

| Name  | Role |
|-------|------|
| Alice | Dev  |

This sentence follows the table.
A table only ends at a blank line or another block such as a heading or list. A plain line directly under the last row becomes one more row. Leave a blank line after the table.

Quick Reference

SyntaxWhat it does
| --- | --- |Required delimiter row, directly under the header
| - |Shortest delimiter cell the GFM spec allows; use --- for portability
---No colon: no alignment set, so the renderer default applies (usually left)
:---Left-align the column
:---:Center-align the column
---:Right-align the column
\|Literal pipe in a cell, including inside `inline code`
<br>Line break inside a cell (<br /> in MDX)
| | |Empty header cells: the closest thing to a table with no header

Platform Support

Tables are not part of the CommonMark spec. They come from GitHub Flavored Markdown, and most major platforms have adopted the extension, but not all.

PlatformSupportsNotes
GitHubYesFull GFM tables: alignment, inline formatting, and <br> in cells. Raw HTML tables keep colspan, rowspan, and width; style attributes are stripped.
GitHub WikisYesSame table syntax as repositories, issues, and pull requests.
GitLabYesGFM tables plus <br> for line breaks, and a ```json:table code block that renders JSON data as a table.
NotionPartialYou cannot type a pipe table, but pasting one creates a simple table. Use /table to build one by hand.
ObsidianYesRenders in Live Preview and Reading view. In Live Preview, right-click a table to add, delete, move, or sort rows and columns.
VS Code previewYesThe built-in preview (markdown-it) renders GFM tables with alignment.
RedditYesBoth www.reddit.com and old Reddit render pipe tables in the Markdown editor. Keep the outer pipes.
DiscordNoPipe tables render as literal text. Line the columns up inside a code block instead.
SlackPartialNot in messages you type, and not in mrkdwn. Apps can send a pipe table inside a Block Kit markdown block (since March 2026) or use the table block.
CommonMarkNoTables are a GFM extension, not part of the CommonMark spec. Pipe rows render as a paragraph.
PandocYesPipe tables, plus grid tables, which allow lists and code blocks inside cells.
Docusaurus / VitePress / AstroYesDocusaurus and Astro (remark-gfm) and VitePress (markdown-it) render GFM tables out of the box.

Frequently Asked Questions

How do you create a table in Markdown?

Write the column names on one line separated by pipes (|), then a delimiter row of hyphens under it (| --- | --- |), then one line per data row. The header and delimiter rows are required; data rows are optional. Leading and trailing pipes are optional and the columns do not need to line up, but outer pipes and three hyphens per column are the most portable form.

How do you align columns in a Markdown table?

Add colons to the delimiter row. :--- means left-aligned, :---: means center-aligned, and ---: means right-aligned. The colon goes on the side you want the text flush against. A plain --- sets no alignment, so the renderer's default applies (usually left). You can mix alignments in the same table.

Can you put bold, italic, or links inside a table cell?

Yes. Inline formatting works in cells: **bold**, *italic*, `code`, ~~strikethrough~~, and [links](url). Block elements do not, because a cell is a single line: a list, heading, blockquote, or fenced code block inside a cell renders as literal text. Use <br> for line breaks, or an HTML table for anything more.

Does Markdown support merging cells (rowspan or colspan)?

No. Markdown tables have no merged cells. If you need colspan or rowspan, write the table in raw HTML (<table>, <tr>, <td colspan="2">). GitHub keeps the colspan and rowspan attributes; check your platform allows raw HTML before relying on it.

How do you escape a pipe inside a table cell?

Put a backslash before it: \|. This also applies inside inline code. Table cells are split on pipes before backticks are parsed, so `a | b` in a cell still breaks the cell; write `a \| b` instead. GFM renderers such as GitHub drop the backslash, so the output shows a plain |.

Can you force a line break inside a table cell?

Not with Markdown alone, because pressing Enter ends the row. Insert an HTML <br> instead: Line 1<br>Line 2. It works on GitHub, GitLab, and VS Code. In MDX, which Docusaurus uses for every file by default, write the self-closing <br /> form, because a bare <br> is a build error.

Can a Markdown table have no header row?

No. GitHub Flavored Markdown requires a header row followed by the delimiter row. The usual workaround is to leave the header cells empty (| | | over | --- | --- |), which renders an empty header row, or to use an HTML table.

How do I set column width in a Markdown table?

Markdown has no syntax for it: the renderer sizes each column to its content, and the number of hyphens in the delimiter row does not change the width on GitHub. For fixed widths, use an HTML table with a width attribute. GitHub keeps width but strips style attributes.

Why is my Markdown table not rendering?

The usual causes: (1) the delimiter row (| --- |) is missing; (2) the delimiter row has a different number of cells than the header row; (3) the table is indented four or more spaces, which turns it into a code block; (4) the platform does not support tables at all, such as Discord or a CommonMark-only parser. GitHub's docs also ask for a blank line before the table. Its renderer does not strictly need one, but adding it never hurts.

Are tables part of CommonMark?

No. CommonMark has no table syntax. Pipe tables come from GitHub Flavored Markdown (GFM), a superset of CommonMark, and most modern renderers include the GFM table extension. A strict CommonMark parser renders the rows as an ordinary paragraph.

Do Markdown tables work on Discord and Slack?

Discord: no, pipe tables render as literal text. Slack: not in messages you type and not in mrkdwn, but apps can post one inside a Block Kit markdown block or use the dedicated table block. On both, the quick workaround is to line the columns up with spaces inside a code block, where the monospace font keeps them aligned.

How many columns can a Markdown table have?

There is no limit in the syntax. The practical limit is readability: wide tables scroll sideways on GitHub and on phones. If a table has too many columns to read comfortably, split it into several tables or transpose rows and columns.