Markdown Split Columns Guide - Multi-Column Layout Methods & Code Examples

Every time you want to place two pieces of content side by side in Markdown, you hit the same wall: Markdown has no column syntax. No :::columns, no {.split}, nothing.

This actually makes sense. Markdown's original design goal was "an easy-to-read, easy-to-write plain text format" [^1], and multi-column layout is fundamentally a typesetting problem — not something plain text should worry about. But that doesn't mean you're stuck. This article covers every practical method for creating columns in Markdown, including which ones work where, which platforms block them, and the actual code for each approach.

Why Doesn't Markdown Have Native Column Syntax?

Short answer: neither the CommonMark spec [^1] nor GitHub Flavored Markdown (GFM) defines any column or multi-column syntax. This isn't an oversight — it's a deliberate design choice.

Markdown's core philosophy is that "the source itself should be readable." Multi-column layout is a visual concept. A plain text file can't express "put A on the left and B on the right" in a way that makes sense without a renderer. You see two paragraphs side by side in plain text, and without rendering, you can't tell they're supposed to be columns.

So if you need columns in Markdown, every method boils down to embedding HTML and CSS. Once you understand this, nothing below will surprise you.

Method 1: HTML + CSS Flexbox (Most Common)

This is the most versatile and widely-used approach. The idea is simple: use HTML <div> tags with CSS Flexbox layout.

Basic Two-Column Layout

<div style="display: flex; gap: 20px;">
  <div style="flex: 1;">

### Left Column

Markdown content for the left column goes here.

  </div>
  <div style="flex: 1;">

### Right Column

Markdown content for the right column goes here.

  </div>
</div>

Key details:

  • display: flex enables flex layout
  • flex: 1 makes both columns equal width; change to flex: 2 to make one wider
  • gap: 20px controls spacing between columns
  • Each <div> can contain regular Markdown — if your renderer supports Markdown parsing inside HTML blocks

I once wrote a README for a project and excitedly put two <div style="flex:1"> blocks side by side to display API docs and example code. Pushed to GitHub, and both sections sat neatly in a single vertical column. The style attributes were stripped entirely. Turns out GitHub filters all custom styles for security reasons [^3].

Three-Column Layout

Just extend the structure:

<div style="display: flex; gap: 16px;">
  <div style="flex: 1;">

#### Column One

Content A

  </div>
  <div style="flex: 1;">

#### Column Two

Content B

  </div>
  <div style="flex: 1;">

#### Column Three

Content C

  </div>
</div>

Unequal Width Columns

For a sidebar effect (e.g., 3:7 ratio):

<div style="display: flex; gap: 20px;">
  <div style="flex: 3;">

### Main Content

Primary content here.

  </div>
  <div style="flex: 7;">

### Sidebar

Supporting info here.

  </div>
</div>

Flexbox's strength is flexibility — change one number to adjust the width ratio, add a <div> to add a column. The downside is verbose code, and not every Markdown renderer parses Markdown syntax inside HTML tags. More on that in the platform compatibility section below.

Method 2: HTML + CSS Grid

CSS Grid is another modern layout option. The difference from Flexbox is that Grid handles two-dimensional layouts — rows and columns simultaneously. For simple column splits, Grid and Flexbox produce similar results, but Grid can be more concise:

<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">

### Left Column

Content for the left side.

### Right Column

Content for the right side.

</div>

Three columns:

<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px;">

#### Col One
Content A

#### Col Two
Content B

#### Col Three
Content C

</div>

Grid's advantage is that grid-template-columns defines column count and ratios in a single line — for instance, 2fr 1fr means the left column takes 2/3 and the right takes 1/3. Compared to Flexbox where you set flex on each child, Grid centralizes the layout logic in one place.

That said, Grid has the same dependency on your rendering environment as Flexbox.

Method 3: CSS column-count (Best for Automatic Text Columns)

If your goal is "automatically split a long block of text into multiple columns" (like newspaper layout), CSS column-count [^2] is the most direct solution:

<div style="column-count: 2; column-gap: 30px;">

This is a long paragraph of text. When the content is long enough, the browser will automatically split it into two columns, similar to newspaper layout. This method doesn't require you to manually divide content — the browser calculates column height and content distribution based on the container width.

It works best for blockquotes, long paragraphs, or list content that benefits from automatic multi-column display. If your content is short, you might not see the column effect since column-count only produces real columns when content overflows.

</div>

Three columns just needs one number change:

<div style="column-count: 3; column-gap: 24px;">

Long text content...

</div>

The key difference between column-count and Flexbox/Grid: column-count is automatic flow — you don't manually decide which content goes in which column. The browser distributes content sequentially across columns. Flexbox/Grid require you to explicitly partition content into each column.

When to use column-count:

  • Automatic text columns (newspaper-style)
  • List items spread across columns
  • When you don't need manual control over per-column content

When not to use it:

  • Left/right columns with different content (e.g., code on the left, explanation on the right)
  • Columns containing complex block-level Markdown elements (headings, code blocks may get cut off)

Method 4: Using Tables to Simulate Columns

When you don't want to touch HTML at all, Markdown tables can create a "looks like columns" effect:

| Left Column | Right Column |
|------------|-------------|
| Content for the left side, text and links | Content for the right side |
| Supports multiple rows | Each row is a "row" |

The advantage is pure Markdown — almost every renderer supports tables. The downsides are significant:

  • Wrong semantics: Tables are for data, not layout. Screen readers will interpret this as tabular data, which is misleading
  • Limited formatting: Table cells can't contain headings, code blocks, blockquotes, or other block-level elements — only inline content
  • No width control: Column widths are determined by content, not by you

Table-based columns work for simple cases. If you just need short text on each side and don't want HTML, tables are fine. But for anything more complex, stick with HTML+CSS.

Honestly, Flexbox is what I use day-to-day. Most Markdown editors and static site generators handle it fine, and it's not that much code to write.

Platform-Specific Column Support

The methods above all work in theory, but real-world results depend on your platform. Here's what you need to know — lessons learned the hard way, so you don't have to repeat them.

Obsidian

Obsidian supports HTML tags in Markdown, so Flexbox and Grid both work. But Obsidian has a better option: CSS Snippets [^4].

Create a CSS file in Obsidian's snippets folder:

/* Create columns.css in .obsidian/snippets/ */
.columns-two {
  display: flex;
  gap: 20px;
}
.columns-two > div {
  flex: 1;
}

Then use it in your Markdown:

<div class="columns-two">

### Left Column

Content...

<div>

### Right Column

Content...

</div>
</div>

CSS snippets separate styling from content, keeping your Markdown files cleaner.

One thing to watch out for: Obsidian's "Reading View" and "Live Preview" modes don't always render HTML identically. I've found that Flexbox columns display correctly in Reading View, but Live Preview occasionally shows raw <div> tags. If you're using Obsidian, treat Reading View as the source of truth.

There's also a Multi-Column Markdown community plugin that adds custom ---start-multi-column--- syntax. It's powerful — supports column width ratios, borders, shadows, and more. The catch is that this syntax only works in Obsidian. Move the file to another editor and it's just noise.

MkDocs (Static Site Generator)

If you're building a documentation site with MkDocs, the Material theme has built-in Grid and Tab components [^5]. The syntax uses extended Markdown:

<div class="grid cards" markdown>

-   ## Card One

    Content A

-   ## Card Two

    Content B

</div>

This is much more convenient than writing CSS yourself, but it's limited to the MkDocs Material theme. Other static site generators (Hugo, Jekyll, etc.) generally support HTML+CSS columns in templates, but you'll need to write your own styles.

Hugo users can leverage Hugo-specific markdown attributes, adding class names like {.c .c2} after content blocks and pairing them with CSS. This approach is cleaner than raw HTML, but only works in Hugo.

GitHub

This is where most people get frustrated: GitHub strips style attributes from HTML when rendering Markdown [^3]. Every method above that uses style="display: flex" will not work on GitHub — the style attribute gets removed entirely.

So in GitHub READMEs, Issues, and comments, Flexbox, Grid, and column-count are all off the table. Your only option is table-based column simulation, and even that has limited effect.

This is a deliberate security decision — GitHub only allows a small set of HTML tags and attributes through its sanitization pipeline. All custom styles are filtered out. It's not a bug.

If you absolutely need side-by-side content on GitHub, your best bet is an HTML <table> without any style attributes, with inline content only in <td> cells. This is basically the same as a Markdown table, though HTML tables tend to handle Markdown parsing inside <td> a bit better.

Other Editors

  • Typora: Supports HTML+CSS columns since Typora renders locally in a browser engine — full CSS works
  • VS Code Preview: Depends on your preview extension. Most use a local browser view, so HTML+CSS methods usually work
  • Notion: Not standard Markdown — it has its own native column feature (drag to split), unrelated to the methods discussed here
  • Pandoc: Fenced divs (::::) can define content blocks, paired with CSS for column layouts. Good choice when generating PDFs

Responsive: What Happens on Mobile?

Flexbox and Grid don't automatically collapse to single-column on small screens. If you need responsive behavior, you'll need flex-wrap: wrap (Flexbox) or media queries.

Adding media queries inside raw Markdown is impractical — you can't write @media rules in a single Markdown file. This is typically handled at the site-level CSS. If your columns will be published on the web, add this to your external CSS:

@media (max-width: 768px) {
  .columns-two, .columns-three {
    flex-direction: column;
  }
}

For Obsidian users, this isn't a concern — Obsidian doesn't have a "mobile rendering" mode. But if your Markdown is published on the web, responsive columns are something you need to plan for.

Method Comparison: Which One to Use

Based on your scenario, here's a quick decision guide:

ScenarioRecommended MethodWhy
Personal notes (Obsidian)CSS SnippetsReusable styles, clean content
Docs site (MkDocs)Built-in GridNative theme support, best results
Docs site (Hugo)Markdown attributes + CSSHugo-specific, clean code
Static websiteFlexbox or GridFull control, good compatibility
GitHub READMETable simulationOnly option that works
Long text auto-columnscolumn-countAutomatic distribution
Blog / general MarkdownFlexboxWidest compatibility
PDF generationPandoc fenced divs + CSSSupports both HTML and LaTeX output

One more thing to check upfront: does your Markdown renderer support Markdown parsing inside HTML tags? Some renderers (like kramdown, MkDocs's parser) handle this fine; others don't. If your renderer doesn't support it, Markdown syntax inside <div> tags will appear as plain text.

A quick test: create a file with ### Test Heading inside a <div>. If it renders as a heading, you're good. If it shows as plain text, your renderer doesn't support Markdown inside HTML blocks, and you'll need to write the content in HTML as well.

Common Questions

What happens to columns on mobile?

Flexbox and Grid don't automatically collapse to single-column on small screens. For responsive behavior, you'll need media queries in external CSS or flex-wrap: wrap for Flexbox. In pure Markdown files, this requires site-level CSS handling.

Are there any Markdown extensions for native columns?

No widely-adopted extension currently provides native column syntax. Pandoc's fenced divs (::::) can define content blocks but don't provide column styling on their own — you still need CSS. Some platforms (like Gitiles) have their own syntax (|||---|||), but that only works on that platform. This reinforces the point that columns are a styling concern, not a syntax concern.

Why isn't my column code working?

The three most common reasons:

  1. Platform strips style attributes: GitHub and some online editors remove inline styles
  2. Renderer doesn't support Markdown inside HTML: <div> content appears as raw text
  3. Content is too short: column-count needs enough content to produce a visible column effect

Check which methods your platform supports before choosing an approach.

References

[^1]: CommonMark Spec: https://spec.commonmark.org/[^2]: MDN Web Docs - CSS Multi-column Layout: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_multicol_layout[^3]: GitHub Docs - Basic writing and formatting syntax: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax[^4]: Obsidian Help - CSS Snippets: https://help.obsidian.md/Extending+Obsidian/CSS+snippets[^5]: MkDocs Material - Grids: https://squidfunk.github.io/mkdocs-material/reference/grids/