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.
| Name | Role | Location |
|---------|-------------|----------|
| Alice | Developer | NYC |
| Bob | Designer | LA |
| Charlie | PM | London || Name | Role | Location |
|---|---|---|
| Alice | Developer | NYC |
| Bob | Designer | LA |
| Charlie | PM | London |
--- and the table works everywhere. The hyphen count does not set the column width.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.
| Item | Price |
|:-------|----------:|
| Coffee | $3.50 |
| Bagel | $2.50 || Item | Price |
|---|---|
| Coffee | $3.50 |
| Bagel | $2.50 |
| Feature | Status | Score |
|:--------|:------:|------:|
| Dark mode | Yes | 95 |
| SSO | No | 0 || 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.
| Style | Syntax | Result |
|---------|---------------------|---------------|
| Bold | `**bold**` | **bold** |
| Italic | `*italic*` | *italic* |
| Code | `` `code` `` | `code` |
| Link | `[text](url)` | [Docs](https://example.com) || 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.
| Command | What it does |
|--------------|----------------------------|
| `ls \| grep` | Filter a directory listing |
| a \|\| b | Logical OR, as plain text || 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.
| Column | Tall Column |
|--------|-------------|
| A | Line 1<br>Line 2<br>Line 3 |
| B | Single line || Column | Tall Column |
|---|---|
| A | Line 1 Line 2 Line 3 |
| B | Single line |
<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 |Broken
| Name | Role | Team |
|------|------|
| Alice | Dev | Core |Fixed
| Name | Role | Team |
|-------|------|------|
| Alice | Dev | Core |Broken
| Command | Use |
|---------|-----|
| `ls | grep x` | Filter |Fixed
| Command | Use |
|---------|-----|
| `ls \| grep x` | Filter |Broken
| Name | Role |
|-------|------|
| Alice | Dev |
This sentence was meant to follow the table.Fixed
| Name | Role |
|-------|------|
| Alice | Dev |
This sentence follows the table.Quick Reference
| Syntax | What 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.
| Platform | Supports | Notes |
|---|---|---|
| GitHub | Yes | Full GFM tables: alignment, inline formatting, and <br> in cells. Raw HTML tables keep colspan, rowspan, and width; style attributes are stripped. |
| GitHub Wikis | Yes | Same table syntax as repositories, issues, and pull requests. |
| GitLab | Yes | GFM tables plus <br> for line breaks, and a ```json:table code block that renders JSON data as a table. |
| Notion | Partial | You cannot type a pipe table, but pasting one creates a simple table. Use /table to build one by hand. |
| Obsidian | Yes | Renders in Live Preview and Reading view. In Live Preview, right-click a table to add, delete, move, or sort rows and columns. |
| VS Code preview | Yes | The built-in preview (markdown-it) renders GFM tables with alignment. |
| Yes | Both www.reddit.com and old Reddit render pipe tables in the Markdown editor. Keep the outer pipes. | |
| Discord | No | Pipe tables render as literal text. Line the columns up inside a code block instead. |
| Slack | Partial | Not 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. |
| CommonMark | No | Tables are a GFM extension, not part of the CommonMark spec. Pipe rows render as a paragraph. |
| Pandoc | Yes | Pipe tables, plus grid tables, which allow lists and code blocks inside cells. |
| Docusaurus / VitePress / Astro | Yes | Docusaurus 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.