Markdown table formatting
Basic table syntax
| Column A | Column B |
| --- | --- |
| Value A | Value B |
Rendered:
| Column A | Column B |
|---|---|
| Value A | Value B |
Required parts
| Column A | Column B |
Header row.
| --- | --- |
Separator row.
| Value A | Value B |
Body row.
Blank line before tables
Good:
Text before the table.
| Column A | Column B |
| --- | --- |
| Value A | Value B |
Bad:
Text before the table.
| Column A | Column B |
| --- | --- |
| Value A | Value B |
Outer pipes
Outer pipes are optional.
This works:
| Column A | Column B |
| --- | --- |
| Value A | Value B |
This also works:
Column A | Column B
--- | ---
Value A | Value B
I prefer outer pipes because the raw Markdown is easier to scan.
Column spacing
The columns do not need to be visually aligned.
This works:
| Name | Type |
| --- | --- |
| title | string |
| description | string |
This also works:
| Name | Type |
| ----------- | ------ |
| title | string |
| description | string |
Aligned columns are easier to read in raw Markdown, but they are not required.
Separator row
Each column needs at least three hyphens.
Good:
| Name | Type |
| --- | --- |
| title | string |
Also good:
| Name | Type |
| -------- | -------- |
| title | string |
Column alignment
Use colons in the separator row.
| Left | Center | Right |
| :--- | :---: | ---: |
| Text | Text | 100 |
| Text | Text | 250 |
Rendered:
| Left | Center | Right |
|---|---|---|
| Text | Text | 100 |
| Text | Text | 250 |
Syntax:
| :--- | left aligned |
| :---: | center aligned |
| ---: | right aligned |
Inline formatting inside cells
| Syntax | Result |
| --- | --- |
| `code` | Inline code |
| **bold** | Bold text |
| *italic* | Italic text |
| [link](https://example.com) | Link |
Rendered:
| Syntax | Result |
|---|---|
code | Inline code |
| bold | Bold text |
| italic | Italic text |
| link | Link |
Escaping pipes inside cells
Use \| when I need to show a literal pipe character.
| Character | Markdown |
| --- | --- |
| Pipe | `\|` |
Rendered:
| Character | Markdown |
|---|---|
| Pipe | | |
Without the backslash, Markdown reads the pipe as a column separator.
Line breaks inside cells
Markdown tables are bad for multi-line content.
Avoid this:
| Task | Notes |
| --- | --- |
| Build layout | First line
Second line |
Use a shorter single-line value instead:
| Task | Notes |
| --- | --- |
| Build layout | First line. Second line. |
Or switch to HTML when the cell content needs real structure.
Raw HTML table
Use HTML when Markdown table syntax gets too limited.
<table>
<caption>Project phases</caption>
<thead>
<tr>
<th>Phase</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Research</td>
<td>Understand the context.</td>
</tr>
<tr>
<td>Strategy</td>
<td>Decide the direction.</td>
</tr>
</tbody>
</table>
Styling Markdown tables
Markdown creates the table HTML, but the visual styling comes from CSS.
For notes, I style tables from the Markdown layout.
---
// This is a .astro layout file
const { frontmatter } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{frontmatter.title}</title>
</head>
<body>
<main class="markdown-content">
<slot />
</main>
</body>
</html>
<style>
.markdown-content :global(table) {
display: block;
max-width: 100%;
overflow-x: auto;
border-collapse: collapse;
white-space: nowrap;
}
.markdown-content :global(th),
.markdown-content :global(td) {
border: 1px solid currentColor;
padding: 0.5rem 0.75rem;
text-align: left;
}
</style>
Styling notes
display: block;
Allows the table to behave like a scrollable block.
max-width: 100%;
Keeps the table inside the note content width.
overflow-x: auto;
Adds horizontal scroll when the table is wider than the container.
border-collapse: collapse;
Makes table borders share a single line instead of doubling up.
white-space: nowrap;
Stops cell text from wrapping, so wide tables scroll instead of breaking lines.
border: 1px solid currentColor;
Adds visible borders using the current text color.
padding: 0.5rem 0.75rem;
Adds spacing inside cells.
My default Markdown table pattern
| Name | Type | Notes |
| --- | --- | --- |
| `title` | `string` | Page title |
| `description` | `string` | Short summary |
| `tags` | `string[]` | Note categories |
My default CSS pattern
.markdown-content :global(table) {
display: block;
max-width: 100%;
overflow-x: auto;
border-collapse: collapse;
white-space: nowrap;
}
.markdown-content :global(th),
.markdown-content :global(td) {
border: 1px solid currentColor;
padding: 0.5rem 0.75rem;
text-align: left;
}