Documentation
Home · Docs · Markdown · Markdown tables: syntax, alignment, and escaping

Markdown tables: syntax, alignment, and escaping

How to make a table in Markdown with pipes and column alignment. Copy-paste examples, escaping pipes, and a free Markdown table generator.

To make a table in Markdown, write a header row, add a delimiter row of hyphens beneath it, then add one or more data rows, separating every cell with a pipe character (|). The delimiter row is what turns the lines into a table, and colons in it set column alignment. A table is a grid of rows and columns built from these pipes. Tables are not part of core Markdown, they are an extension in GitHub Flavored Markdown, MultiMarkdown, Markdown Extra, and Pandoc.

Prefer not to align pipes by hand? Build a table visually with the Markdown table generator, then copy the clean Markdown into your document.

Markdown tables syntax reference

Goal Syntax
Header and body \| A \| B \| then \| --- \| --- \|
Left align \| :--- \|
Center align \| :---: \|
Right align \| ---: \|
Escape a pipe \\| inside a cell

Markdown tables key facts

  • A Markdown table needs three parts: a header row, a delimiter row of hyphens, and at least one data row, with cells separated by pipes (|).
  • The delimiter row is required. Without the row of hyphens under the header, the lines render as a plain paragraph, not a table.
  • Colons in the delimiter row set alignment: :--- is left, :---: is center, and ---: is right.
  • The source pipes do not need to line up. The parser reads the pipes, not the spacing, so ragged columns still render correctly.
  • To show a literal pipe inside a cell, escape it with a backslash (\|), or it is read as a column separator.
  • Tables are an extension, not core Markdown. They work on GitHub, in MultiMarkdown, Markdown Extra, and Pandoc, but not in strict CommonMark, Slack, or Discord.

Use a Markdown table only for genuinely tabular data

Tables work best when every row describes the same fields. Use a list for a sequence of points and headings for long prose. Keeping cell content short makes the raw source and narrow-screen output easier to read.

GFM tables do not support row spans, column spans, or reliably portable multi-line cells. Escape literal pipes where the target parser requires it, and keep the delimiter row valid. For complex data, use trusted inline HTML or link to an accessible data format. Add a short introduction that explains what the reader should learn from the table.

Basic syntax

A pipe table needs three parts: a header row, a delimiter row, and at least one data row. Separate every cell with a pipe. The delimiter row uses hyphens and must have one dash group per column.

Markdown

| Language | Extension |
| -------- | --------- |
| Python   | .py       |
| Ruby     | .rb       |

Rendered output

Language Extension
Python .py
Ruby .rb

HTML output

<table>
  <thead>
    <tr>
      <th>Language</th>
      <th>Extension</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Python</td>
      <td>.py</td>
    </tr>
    <tr>
      <td>Ruby</td>
      <td>.rb</td>
    </tr>
  </tbody>
</table>

The cell widths in the source do not need to line up. The parser reads the pipes, not the spacing, so | A | B | and |A|B| produce the same table. Aligning columns in the raw text only helps humans read the source.

A 2x2 table

A 2x2 table has two columns and two data rows beneath the header, a common shape for a small comparison or matrix. It is built like any other pipe table: a header row, a delimiter row with two dash groups, then two data rows.

Markdown

| Column A | Column B |
| -------- | -------- |
| A1       | B1       |
| A2       | B2       |

Rendered output

Column A Column B
A1 B1
A2 B2

HTML output

<table>
  <thead>
    <tr>
      <th>Column A</th>
      <th>Column B</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A1</td>
      <td>B1</td>
    </tr>
    <tr>
      <td>A2</td>
      <td>B2</td>
    </tr>
  </tbody>
</table>

For a labeled 2x2 matrix, leave the top-left header cell empty and use the first column for row labels, so both axes are named. The same shape scales up to any grid: add more dash groups for more columns, and more lines for more rows.

The header row and delimiter row

Every pipe table has a header row on the first line and a delimiter row directly beneath it. The delimiter row is what turns the block into a table. Without it, the parser treats the lines as an ordinary paragraph with literal pipes.

Markdown

| Header A | Header B |
| -------- | -------- |
| Cell 1   | Cell 2   |

Rendered output

Header A Header B
Cell 1 Cell 2

The delimiter row needs at least one hyphen per column. | - | - | works, and so does | ---- | ---- |. The number of columns in the delimiter row sets the column count for the whole table. Most flavors require the delimiter row to have the same number of columns as the header.

The leading and trailing pipes are optional in GFM, MultiMarkdown, Markdown Extra, and Pandoc. Both of these produce the same table:

Markdown

Header A | Header B
-------- | --------
Cell 1   | Cell 2

Rendered output

Header A Header B
Cell 1 Cell 2

Keeping the outer pipes is clearer and more portable, so prefer them.

Column alignment

Add a colon to the delimiter row to set alignment. A colon on the left aligns left, a colon on both sides centers, and a colon on the right aligns right. A plain --- uses the renderer default, which is usually left.

Markdown

| Left | Center | Right |
| :--- | :----: | ----: |
| a    | b      | c     |
| dd   | ee     | ff    |

Rendered output

Left Center Right
a b c
dd ee ff

HTML output

<table>
  <thead>
    <tr>
      <th style="text-align:left">Left</th>
      <th style="text-align:center">Center</th>
      <th style="text-align:right">Right</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align:left">a</td>
      <td style="text-align:center">b</td>
      <td style="text-align:right">c</td>
    </tr>
    <tr>
      <td style="text-align:left">dd</td>
      <td style="text-align:center">ee</td>
      <td style="text-align:right">ff</td>
    </tr>
  </tbody>
</table>

Renderers express alignment differently. Some emit an inline style attribute, some emit an align attribute, and some emit an alignment class. The visual result is the same.

Escaping pipes inside cells

A literal pipe inside a cell would be read as a column separator. Escape it with a backslash (\|) so it appears as text.

Markdown

| Operator | Meaning        |
| -------- | -------------- |
| \|\|     | logical or     |
| &&       | logical and    |

Rendered output

Operator Meaning
|| logical or
&& logical and

If the pipe is inside inline code, some parsers still treat it as a separator, so escaping is the safe approach even within backticks. When a table gets crowded with escaped pipes, consider showing that content as a fenced code block instead.

Inline formatting inside cells

Cells accept inline Markdown such as bold, italic, links, and inline code. Block elements like lists, blockquotes, and fenced code blocks are not allowed inside a pipe table cell.

Markdown

| Feature   | Note                              |
| --------- | --------------------------------- |
| **Bold**  | Use `**text**`                    |
| *Italic*  | Use `*text*`                      |
| [Link](https://markdific.com) | Standard link syntax |

Rendered output

Feature Note
Bold Use **text**
Italic Use *text*
Link Standard link syntax

To force a line break inside a cell, most GFM renderers accept a <br> tag, since a raw newline is not allowed within a single-line pipe table cell.

Empty cells and ragged rows

You can leave a cell empty by putting nothing between two pipes. If a data row has fewer cells than the header, the missing trailing cells render empty. If it has more, the extra cells are usually dropped.

Markdown

| Name  | Role      |
| ----- | --------- |
| Ada   | Engineer  |
| Grace |           |
| Alan  | Scientist |

Rendered output

Name Role
Ada Engineer
Grace
Alan Scientist

Tables on GitHub

GitHub renders pipe tables through GitHub Flavored Markdown, so the syntax on this page works in READMEs, issues, pull requests, and discussions. Use a header row, a hyphen delimiter row, and optional colons for alignment. Escape a literal pipe inside a cell with \|.

GitHub table cells hold inline content. Use <br> only when a line break is genuinely needed and allowed in that context. Source columns do not have to line up because the parser reads the pipes rather than the visual spacing. For other GitHub extensions, see Markdown on GitHub.

Flavor differences

Tables are an extension feature. Core CommonMark does not include them at all, so a strict CommonMark renderer prints the raw pipes as text. Every other major flavor supports pipe tables, with small differences in optional features.

Flavor Table support Notes
CommonMark No Not in the core spec. Pipe rows render as a plain paragraph unless a table extension is enabled.
GitHub Flavored Markdown (GFM) Yes Pipe tables defined as a GFM extension. Header row, delimiter row, colon alignment, and \| escaping supported.
MultiMarkdown Yes Pipe tables with alignment. Also adds captions, column spans, and multi-body sections not found in GFM.
Markdown Extra Yes Pipe table syntax that GFM and Pandoc mirror. Cells limited to inline content on a single line.
Pandoc Yes Supports pipe tables plus simple, multiline, and grid table styles for more complex layouts.

CommonMark leaves tables out of the core specification on purpose, so support depends on whether a table extension is enabled. GFM formally defines pipe tables as an extension. MultiMarkdown and Pandoc go further with extra table styles: MultiMarkdown adds captions and cell spanning, and Pandoc adds grid and multiline tables that can hold block content. Markdown Extra introduced the pipe table syntax that the others adopted.

Other platforms (Slack, Discord, Reddit, Obsidian, Notion)

  • Slack and Discord: neither renders Markdown tables. Pasted pipe syntax shows as literal text, so use a code block or an image for tabular data.
  • Reddit: supports GFM-style pipe tables in the newer editor and in most subreddits that allow Markdown.
  • Obsidian: full pipe table support with alignment, plus a live table editor.
  • Notion: does not parse pasted Markdown pipe tables into its native table blocks. It creates tables through its own block interface.

For the full comparison of how flavors differ across all elements, see Markdown flavors.

How Markdific renders it

Markdific renders pipe tables as formatted tables with a header row and aligned columns, and it honors colon alignment in the delimiter row.

Inline formatting inside cells, including bold, italic, links, and inline code, is rendered normally.

Try it in the Markdific online editor.

Common mistakes and gotchas

  • Missing the delimiter row. Without the row of hyphens under the header, the block is a paragraph, not a table. This is the most common table failure.
  • Mismatched column counts. The delimiter row should have the same number of columns as the header. A mismatch can drop the table or misalign cells.
  • Unescaped pipes in content. A raw | inside a cell splits it into two columns. Escape it as \|.
  • Expecting tables in CommonMark, Slack, or Discord. These do not render pipe tables. The pipes show as text.
  • Trying to put block content in a cell. Lists, blockquotes, and fenced code blocks do not work inside pipe table cells. Use a <br> for a simple line break, or restructure.
  • Relying on source alignment. Lining up columns in the raw text is only for readability. The parser ignores the spacing.
  • No blank line before the table. Some parsers need a blank line between a preceding paragraph and the table for it to be recognized.

Best practices

  • Always include the delimiter row directly under the header.
  • Keep the leading and trailing outer pipes for clarity and portability.
  • Match the column count across the header, delimiter, and data rows.
  • Set alignment explicitly with colons when it matters, especially for numeric columns that read better right aligned.
  • Escape literal pipes as \| inside cells.
  • Keep cell content to inline elements. For anything with block structure, use a fenced code block or restructure the content.
  • Add a blank line before and after the table.

HTML equivalent

Markdown pipe tables compile to a full HTML <table> with a <thead> for the header row and a <tbody> for the data rows. Alignment maps to a style or alignment attribute on each cell.

Markdown

| Item | Qty |
| :--- | --: |
| Pens | 12  |
| Ink  | 3   |

HTML output

<table>
  <thead>
    <tr>
      <th style="text-align:left">Item</th>
      <th style="text-align:right">Qty</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align:left">Pens</td>
      <td style="text-align:right">12</td>
    </tr>
    <tr>
      <td style="text-align:left">Ink</td>
      <td style="text-align:right">3</td>
    </tr>
  </tbody>
</table>

FAQ

How do you make a table in Markdown? Write a header row with cells separated by pipes, add a delimiter row of hyphens beneath it with one dash group per column, then add data rows. For example, a header line, a line of hyphens, and one or more rows of data.

How do you make a 2x2 table in Markdown? Write a header row with two columns, add a delimiter row with two dash groups, then add two data rows. For a labeled 2x2 matrix, leave the top-left header cell empty and use the first column for row labels.

Are tables part of standard Markdown? No. Tables are not in core CommonMark or classic Markdown. They are an extension provided by GitHub Flavored Markdown, MultiMarkdown, Markdown Extra, and Pandoc.

How do you align columns in a Markdown table? Add colons to the delimiter row. A colon on the left aligns left, colons on both sides center, and a colon on the right aligns right.

How do you put a pipe character inside a table cell? Escape it with a backslash, writing a backslash before the pipe. This tells the parser to treat the pipe as text rather than a column separator.

Why is my Markdown table not rendering? The most common cause is a missing delimiter row, the row of hyphens under the header. Other causes are a mismatched column count or a renderer that does not support tables, such as core CommonMark, Slack, or Discord.

Can a table cell contain a list or code block? No. Pipe table cells hold only inline content such as text, bold, italic, links, and inline code. For a line break inside a cell, most GFM renderers accept a <br> tag.

Do Markdown tables work on GitHub? Yes. GitHub Flavored Markdown supports pipe tables with the header row, delimiter row, colon alignment, and escaped pipes.

Sources and compatibility references

Use these primary references for syntax rules. Renderer behaviour can still vary by version and configuration, so preview important documents in their final destination.