Container & Columns
Constrain page width with the container utility or the max-w-* pattern, and flow text into newspaper-style columns with the columns-* utilities.
Two related jobs: keeping content from stretching too wide, and splitting content into columns.
The container utility#
container sets max-width to the current breakpoint, so the element steps up in width as the viewport grows.
| Breakpoint | container max-width |
|---|---|
Below sm | 100% |
sm | 40rem |
md | 48rem |
lg | 64rem |
xl | 80rem |
2xl | 96rem |
<div class="container mx-auto px-6">…</div>Customising container#
Because container is now an ordinary utility, you override it with @utility:
@import "tailwindcss";
@utility container {
margin-inline: auto;
padding-inline: --spacing(6);
}Now class="container" alone is centred and padded.
The max-w-* pattern Recommended#
Most modern layouts skip container entirely and use an explicit max width:
<div class="mx-auto max-w-7xl px-6 lg:px-8">…</div>Why this is usually better:
- The width is stated, not derived from breakpoints.
- It does not jump at breakpoints — it grows smoothly to a ceiling.
- Different sections can use different ceilings (
max-w-3xlfor prose,max-w-7xlfor a grid).
| Utility | Width | Good for |
|---|---|---|
max-w-prose | ~65 characters | Body copy |
max-w-3xl | 48rem | Articles, forms |
max-w-5xl | 64rem | Documentation |
max-w-7xl | 80rem | Marketing pages, dashboards |
max-w-screen-lg | The lg breakpoint | Matching a breakpoint exactly |
<div class="space-y-3 bg-gray-50 p-4 text-sm">
<div class="mx-auto max-w-sm rounded bg-indigo-100 p-3 text-center text-indigo-900">max-w-sm</div>
<div class="mx-auto max-w-md rounded bg-indigo-100 p-3 text-center text-indigo-900">max-w-md</div>
<div class="mx-auto max-w-2xl rounded bg-indigo-100 p-3 text-center text-indigo-900">max-w-2xl</div>
</div>max-w-* draws from the --container-* theme namespace, which is the same namespace that powers container query variants.
Multi-column text#
columns-* flows content into newspaper-style columns. The browser balances the content automatically.
| Utility | CSS |
|---|---|
columns-2 … columns-12 | Fixed column count |
columns-3xs … columns-7xl | Ideal column width; count adapts |
columns-auto | Browser decides |
gap-8 | Gutter between columns |
<div class="p-4">
<div class="columns-1 gap-6 text-sm text-gray-700 sm:columns-2">
<p class="mb-3">Utility-first CSS trades a small amount of markup verbosity for a large reduction in stylesheet complexity. Instead of naming every piece of UI, you describe the result directly.</p>
<p class="mb-3">The trade pays off most in codebases with a component layer, because repetition collapses into the component rather than into a CSS class.</p>
<p class="mb-3">Where there is no component layer — static HTML, CMS output — the calculus changes, and hand-written CSS built from theme variables is often the better answer.</p>
</div>
</div>Controlling breaks#
| Utility | Purpose |
|---|---|
break-inside-avoid | Keep an element from splitting across columns |
break-before-column / break-after-column | Force a column break |
break-before-page / break-after-page | Page breaks when printing |
<div class="columns-2 gap-8">
<figure class="mb-4 break-inside-avoid">
<img src="…" alt="">
<figcaption>Stays whole.</figcaption>
</figure>
</div>Masonry-style galleries#
<div class="columns-2 gap-4 md:columns-3">
<img class="mb-4 w-full break-inside-avoid rounded-lg" src="…" alt="">
<img class="mb-4 w-full break-inside-avoid rounded-lg" src="…" alt="">
</div>Choosing an approach#
| Need | Use |
|---|---|
| Page width constraint | mx-auto max-w-7xl px-6 |
| Breakpoint-stepped width | container mx-auto px-6 |
| Readable article width | max-w-prose or max-w-3xl |
| Newspaper text flow | columns-* |
| Card gallery with equal rows | Grid |
| Card gallery with ragged heights | columns-* + break-inside-avoid |
Common mistakes#
- Expecting
containerto centre itself. Addmx-autoin v4. - No horizontal padding.
max-w-7xlalone lets text touch the screen edge on phones. Always pair withpx-*. - Nesting containers. One width constraint per section is enough.
- Using
columns-*for layout. It is for content flow. Anything interactive or order-sensitive belongs in a grid. - Forgetting
break-inside-avoid. Cards and figures split across columns without it.
Related topics#
- Sizing — the full
max-w-*scale - Grid — two-dimensional layout
- Spacing — padding and gutters
- Container Queries — the
--container-*namespace's other job