Markdown tables look intimidating in raw source form — rows of pipes and dashes — but the actual rules behind them are narrow and worth knowing precisely, especially the parts that trip people up.

How Markdown Table Syntax Works

A Markdown table is built from three kinds of rows: a header row, a separator row made of dashes (and optional colons) directly beneath it, and any number of data rows after that — each one a line of cell values separated by pipe characters. The separator row is what actually tells the renderer "this is a table" rather than a coincidence of pipe characters in regular text; without it, the header row and data rows are just plain paragraphs.

What the Alignment Colons Do

Alignment is controlled entirely by colons placed in the separator row, not anywhere in the header or data rows themselves. A colon on the left side of a separator cell (:---) left-aligns that column, one on the right (---:) right-aligns it, and colons on both sides (:---:) center it. Leave a separator cell as plain dashes with no colon, and most renderers fall back to left alignment by default — which is why a table with no alignment specified still renders left-aligned rather than raising an error.

Tip: Alignment is a per-column setting, not per-cell — whatever you set in the separator row for a column applies to every row's value in that column, so you can't left-align one row's cell and center another's within the same column.

Why Tables Aren't Core Markdown

Original Markdown, as designed by John Gruber, never included a table syntax at all — tables were added later as an extension by GitHub Flavored Markdown (GFM), which has since been widely adopted by other platforms and editors. CommonMark, the community specification meant to standardize Markdown's ambiguous parts, still doesn't include tables in its core spec either. In practice this rarely causes problems, since GitHub, GitLab, most static site generators, and most Markdown editors all implement the GFM table extension — but a strictly CommonMark-only parser genuinely won't render one as a table.

Escaping Pipes and Line Breaks

Because the pipe character defines column boundaries, a literal pipe you actually want to display inside a cell has to be escaped as \| — otherwise the parser reads it as the start of a new column and the row structure breaks. Real line breaks inside a cell aren't supported by the core table syntax at all; a plain newline just ends the row. Some renderers accept an HTML <br> tag typed directly inside a cell as a workaround, but that's a renderer-specific extension, not something guaranteed to work everywhere.

Why Padding the Source Doesn't Change Output

It's common to see beautifully aligned pipe characters in a table's raw Markdown source, with extra spaces padding each column to the same width. That padding is entirely cosmetic — parsers only look for the pipe characters themselves, not how many spaces surround them, so a table typed with ragged, unaligned pipes renders identically to one with perfectly lined-up columns. The padding exists purely to make the raw text easier for a human to scan while editing, not because the renderer needs it.

Try It Instantly

Build a table visually in a grid — no manual pipe-counting required — with our free Markdown Table Generator. It handles padding and alignment automatically and gives you correctly formatted GFM code to paste straight into a README or doc.

FAQ

Do the pipe characters need to line up visually in the source? No — Markdown renderers only care about the pipe characters marking column boundaries, not visual alignment in the raw text. This tool does pad the columns neatly anyway, purely to make the raw source easier for a human to read while editing.

What does the column alignment option actually do? It adds colons to the separator row under each header — a colon on the left, right, or both sides tells the renderer to left-align, right-align, or center that column's content. Without any colon, most renderers default to left alignment.

Can a table cell contain a pipe character or a line break? A literal pipe inside a cell needs to be escaped as \| or it will be misread as a new column boundary. Markdown tables also don't support real line breaks inside a cell — some renderers accept an HTML <br> tag as a workaround, but that isn't part of core Markdown table syntax.

Will this table render correctly everywhere, including plain CommonMark? Tables are a GitHub Flavored Markdown (GFM) extension, not part of core CommonMark, so they render correctly on GitHub, GitLab, and most modern Markdown viewers, but may not render as a table on a strictly CommonMark-only parser.

Need a table right now? Try the free Markdown Table Generator — edit cells in a grid, get clean Markdown out.