SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/two-column-layouts

7 CSS Two-Column Layouts

7 Pure CSSPublished 2026-10-05Free · no sign-up

Seven two-column patterns: an article with an aside, columns that switch to one without media queries, equal-height cards with aligned buttons, a half-text half-image section, an aside that comes first on phones, newspaper text columns and a golden-ratio split.

01. Main Content and Aside

Two columnGrid

An article with a narrower aside, as two grid columns of 2fr and 1fr that stack below a container width of 460px. Using minmax(0, 2fr) instead of plain 2fr stops long words or code in the article from forcing the column wider than its share.

View code
<div class="tcl1"><div class="in"><article><h3>Choosing a font pairing</h3><p>Pair one expressive face with one quiet one, and use each for one job.</p></article><aside><b>Quick tip</b><p>Limit yourself to two families.</p></aside></div></div>
.tcl1 { width: 580px; max-width: 100%; container-type: inline-size; font: 14px/1.6 Inter, system-ui, sans-serif; }
.tcl1 .in { display: grid; gap: 14px; }
.tcl1 article { padding: 16px; border-radius: 12px; background: #fff; border: 1px solid #e4e7ec; color: #344054; }
.tcl1 h3 { margin: 0 0 6px; color: #101828; }
.tcl1 aside { padding: 16px; border-radius: 12px; background: #eef4ff; color: #1e3a8a; }
.tcl1 p { margin: 0; }
@container (min-width: 460px) { .tcl1 .in { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); } }

02. Columns That Switch Without Media Queries

Two columnFlexbox

Two flex items whose flex-basis is a calculation: (30rem - 100%) * 999 is a huge positive number when the container is narrow and a huge negative one when it is wide. The result is a clean switch between one column and two at 30rem, with no media query.

View code
<div class="tcl2"><section>Column one</section><section>Column two</section></div>
.tcl2 { display: flex; flex-wrap: wrap; gap: 12px; width: 560px; max-width: 100%; font: 700 14px Inter, system-ui, sans-serif; }
.tcl2 section { flex-grow: 1; flex-basis: calc((30rem - 100%) * 999); padding: 30px 16px; border-radius: 12px; background: #1e293b; color: #e2e8f0; text-align: center; }
.tcl2 section:last-child { background: #312e81; }

03. Equal-Height Columns

Two columnCards

Two plan cards with different amounts of text that still end at the same height, because grid items stretch to the row by default. Inside each card a flex column with margin-top: auto pins the button to the bottom so the buttons line up too.

View code
<div class="tcl3"><article><h3>Starter</h3><p>For trying things out.</p><a href="#starter">Choose</a></article><article><h3>Studio</h3><p>For small teams who need shared libraries, roles, version history and priority support.</p><a href="#studio">Choose</a></article></div>
.tcl3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; width: 440px; max-width: 100%; font: 14px/1.5 Inter, system-ui, sans-serif; }
.tcl3 article { display: flex; flex-direction: column; padding: 16px; border: 1px solid #e4e7ec; border-radius: 14px; background: #fff; color: #475467; }
.tcl3 h3 { margin: 0 0 6px; color: #101828; }
.tcl3 p { margin: 0 0 14px; }
.tcl3 a { margin-top: auto; padding: 9px; border-radius: 8px; background: #101828; color: #fff; font-weight: 700; text-align: center; text-decoration: none; }
.tcl3 a:focus-visible { outline: 3px solid #84adff; outline-offset: 2px; }

04. Text and Image Half and Half

Two columnMedia

A 50/50 split of copy and picture where the picture fills its half completely with object-fit: cover, whatever the text length. Below the breakpoint the image moves above the text and takes a fixed 16:9 ratio so it does not become a thin strip.

View code
<section class="tcl4"><div class="in"><div class="tx"><h3>Made in small batches</h3><p>Every piece is thrown, trimmed and glazed by hand in our Porto studio.</p></div><div class="im" role="img" aria-label="Ceramic bowls drying on a shelf"></div></div></section>
.tcl4 { width: 560px; max-width: 100%; container-type: inline-size; font: 14px/1.6 Inter, system-ui, sans-serif; }
.tcl4 .in { display: grid; border-radius: 16px; overflow: hidden; background: #1c1917; }
.tcl4 .tx { padding: 20px; color: #d6d3d1; } .tcl4 h3 { margin: 0 0 6px; color: #fafaf9; font-size: 20px; } .tcl4 p { margin: 0; }
.tcl4 .im { order: -1; aspect-ratio: 16 / 9; background: repeating-linear-gradient(90deg, #a8a29e 0 30px, #78716c 30px 34px), linear-gradient(#e7e5e4, #a8a29e); }
@container (min-width: 440px) { .tcl4 .in { grid-template-columns: 1fr 1fr; } .tcl4 .im { order: 0; aspect-ratio: auto; min-height: 180px; } .tcl4 .tx { align-self: center; } }

05. Aside First on Mobile

Two columnOrder

On a booking page the price box belongs beside the details on desktop but above them on a phone. The aside comes first in the HTML, which is the order that also suits screen readers, and grid placement moves it to the right column on wide containers.

View code
<div class="tcl5"><div class="in"><aside><b>$120 / night</b><a href="#book">Book now</a></aside><article><h3>Cabin by the lake</h3><p>Two bedrooms, a wood stove and a private jetty.</p></article></div></div>
.tcl5 { width: 560px; max-width: 100%; container-type: inline-size; font: 14px/1.6 Inter, system-ui, sans-serif; }
.tcl5 .in { display: grid; gap: 12px; }
.tcl5 aside { display: grid; gap: 8px; align-content: start; padding: 16px; border: 1px solid #e4e7ec; border-radius: 12px; background: #fff; }
.tcl5 b { color: #101828; font-size: 18px; }
.tcl5 a { padding: 9px; border-radius: 8px; background: #b54708; color: #fff; font-weight: 700; text-align: center; text-decoration: none; }
.tcl5 a:focus-visible { outline: 3px solid #fdb022; outline-offset: 2px; }
.tcl5 article { padding: 16px; border-radius: 12px; background: #fffaeb; color: #475467; }
.tcl5 h3 { margin: 0 0 6px; color: #101828; } .tcl5 p { margin: 0; }
@container (min-width: 460px) { .tcl5 .in { grid-template-columns: 1fr 200px; } .tcl5 aside { grid-column: 2; grid-row: 1; } .tcl5 article { grid-column: 1; grid-row: 1; } }

06. Newspaper Text Columns

Two columnColumns

Long text flowing across two columns like a newspaper, with column-width so a narrow container drops to one column automatically. A column rule separates them, and the heading spans both with column-span: all.

View code
<article class="tcl6"><h3>The case for slower software</h3><p>Fast tools are wonderful until they encourage us to skip the thinking. A short pause before publishing catches more mistakes than any linter.</p><p>The best teams we know build that pause into their process: a review, a walk, a night's sleep. The work is better for it.</p></article>
.tcl6 { width: 520px; max-width: 100%; column-width: 200px; column-gap: 28px; column-rule: 1px solid #e4e7ec; font: 15px/1.65 Georgia, serif; color: #344054; }
.tcl6 h3 { column-span: all; margin: 0 0 10px; color: #101828; font: 800 22px Inter, system-ui, sans-serif; }
.tcl6 p { margin: 0 0 12px; }
.tcl6 p:first-of-type::first-letter { float: left; margin: 4px 6px 0 0; color: #101828; font-size: 46px; line-height: .8; font-weight: 700; }

07. Golden Ratio Columns

Two columnProportion

Columns in the golden ratio, 1.618fr and 1fr, which many designers find more natural than a 2:1 split. fr units make any ratio a one-line change, and the gap is a clamp() that grows with the container.

View code
<div class="tcl7"><div class="in"><section>1.618fr</section><section>1fr</section></div></div>
.tcl7 { width: 560px; max-width: 100%; container-type: inline-size; font: 700 14px "JetBrains Mono", ui-monospace, monospace; }
.tcl7 .in { display: grid; grid-template-columns: 1.618fr 1fr; gap: clamp(8px, 3cqi, 20px); }
.tcl7 section { display: grid; place-items: center; height: 160px; border-radius: 14px; background: linear-gradient(135deg, #b45309, #78350f); color: #fef3c7; }
.tcl7 section + section { background: linear-gradient(135deg, #0f766e, #134e4a); color: #ccfbf1; }

About these CSS Two-Column Layouts

minmax(0, 1fr) beats 1fr

A plain 1fr column will not shrink below its content's minimum width, so a long URL or code block can push it wider than its share. minmax(0, 1fr) lets it shrink and the content wrap or scroll instead.

Source order is reading order

Put content in the HTML in the order it should be read and announced, then use grid placement or order to arrange it visually. Never reorder so far that keyboard focus jumps around the screen.

Stack by container, not screen

A two-column block inside a narrow sidebar should stack even on a wide screen. Container queries switch it based on the space it actually has.

Text columns for text

column-width flows one piece of text into newspaper columns and drops to one column when the container is narrow. Keep it for short reads; long multi-column articles make readers scroll up and down.

Frequently asked questions

Grid or flexbox for two columns?

Grid when the columns have a defined relationship (2:1, fixed and fluid); flexbox when items should wrap based on their own size.

How does the no-media-query switch work?

Its flex-basis is a calculation that is hugely positive below the breakpoint and hugely negative above it, so items jump between full and shared width.

Will these work in older browsers?

Grid and flexbox work everywhere; container queries are supported in all current browsers.