Foundations
Layout
Breakpoints, the container, and page layouts with the Tailwind CSS grid and flex utilities.
Breakpoints
Breakpoints are Tailwind CSS’s minimum viewport widths in rem, compiled into both CSS modes from one configuration; changing them needs a rebuild of the package. Media queries use the browser’s initial font size, so a page or root font size does not move them. A utility with a breakpoint prefix, such as md:grid-cols-2, applies from that width up.
| Key | Minimum | Pixels at 16px |
|---|---|---|
sm | 40rem | 640px |
md | 48rem | 768px |
lg | 64rem | 1024px |
xl | 80rem | 1280px |
2xl | 96rem | 1536px |
Container
container is Tailwind CSS’s: full width, with the active breakpoint’s width as its maximum. Center and pad it with mx-auto px-4; for content that fills its parent at every width, use px-4 alone.
<div class="container mx-auto px-4">
<div class="card"><div class="card-body">Container</div></div>
</div>
<div class="px-4">
<div class="card"><div class="card-body">Full width</div></div>
</div><div class="plf:container plf:mx-auto plf:px-4">
<div class="plf:card"><div class="plf:card-body">Container</div></div>
</div>
<div class="plf:px-4">
<div class="plf:card"><div class="plf:card-body">Full width</div></div>
</div>The maximum includes the padding, and a narrower parent always wins. Put the container inside the data-plf-root element, not on it.
Grid
Lay out equal-width columns with the grid utilities: grid with grid-cols-{1-12}, and a gap. Give the column count for small screens first, usually grid-cols-1, then {breakpoint}:grid-cols-{n} from a wider breakpoint up.
<div class="grid grid-cols-3 gap-4">
<div class="card"><div class="card-body">One</div></div>
<div class="card"><div class="card-body">Two</div></div>
<div class="card"><div class="card-body">Three</div></div>
</div><div class="plf:grid plf:grid-cols-3 plf:gap-4">
<div class="plf:card"><div class="plf:card-body">One</div></div>
<div class="plf:card"><div class="plf:card-body">Two</div></div>
<div class="plf:card"><div class="plf:card-body">Three</div></div>
</div>Responsive columns
Breakpoints measure the viewport, not the parent, so pick counts that fit the grid’s actual width.
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="card"><div class="card-body">Overview</div></div>
<div class="card"><div class="card-body">Details</div></div>
<div class="card"><div class="card-body">Resources</div></div>
<div class="card"><div class="card-body">Next steps</div></div>
</div><div class="plf:grid plf:grid-cols-1 plf:sm:grid-cols-2 plf:lg:grid-cols-4 plf:gap-4">
<div class="plf:card"><div class="plf:card-body">Overview</div></div>
<div class="plf:card"><div class="plf:card-body">Details</div></div>
<div class="plf:card"><div class="plf:card-body">Resources</div></div>
<div class="plf:card"><div class="plf:card-body">Next steps</div></div>
</div>Columns use minmax(0, 1fr), so long content does not widen a column; give wide code or media its own scrolling wrapper. col-span-{1-12} and col-span-full let an item span several columns.
Columns and rows
flex flex-col places items in a column and stretches them to its width. flex flex-wrap items-center places items in a row, centers them vertically and wraps them when the row runs out of room. Add a gap such as gap-4 (16px) between the items.
<div class="flex flex-col gap-4">
<div class="card"><div class="card-body">First</div></div>
<div class="card"><div class="card-body">Second</div></div>
</div><div class="plf:flex plf:flex-col plf:gap-4">
<div class="plf:card"><div class="plf:card-body">First</div></div>
<div class="plf:card"><div class="plf:card-body">Second</div></div>
</div><div class="flex flex-wrap items-center gap-2">
<button class="btn btn-primary">Save changes</button>
<button class="btn btn-outline">Cancel</button>
<span class="badge badge-outline">Draft</span>
</div><div class="plf:flex plf:flex-wrap plf:items-center plf:gap-2">
<button class="plf:btn plf:btn-primary">Save changes</button>
<button class="plf:btn plf:btn-outline">Cancel</button>
<span class="plf:badge plf:badge-outline">Draft</span>
</div>Alignment
items-* aligns the items across the row or column and justify-* along it.
<div class="flex flex-col items-center gap-4">
<button class="btn btn-primary">Primary action</button>
<button class="btn btn-outline">Secondary action</button>
</div>
<div class="flex flex-wrap items-center justify-between gap-4">
<span class="badge badge-outline">3 updates</span>
<button class="btn btn-outline">View activity</button>
</div><div class="plf:flex plf:flex-col plf:items-center plf:gap-4">
<button class="plf:btn plf:btn-primary">Primary action</button>
<button class="plf:btn plf:btn-outline">Secondary action</button>
</div>
<div class="plf:flex plf:flex-wrap plf:items-center plf:justify-between plf:gap-4">
<span class="plf:badge plf:badge-outline">3 updates</span>
<button class="plf:btn plf:btn-outline">View activity</button>
</div>Inside a flex row, add min-w-0 to a column that holds wide content, so it can shrink below the content’s width. A row without flex-wrap does not wrap; put it in a horizontal Scroll Area instead of letting actions overflow. Layout utilities add no surface, clipping or keyboard navigation; add the semantics your content needs.
Sticky and skip links
Set --plf-sticky-offset on the root to the sticky header’s height. Elements stick inside their nearest scroll container, which any ancestor with overflow other than visible becomes.
<div data-plf-root style="--plf-sticky-offset: 4rem">
<a class="btn btn-primary not-focus-within:sr-only" href="#content">Skip to content</a>
<header class="sticky top-0 z-(--plf-z-index-sticky)" style="block-size: var(--plf-sticky-offset)"><!-- Brand and actions --></header>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<nav class="md:sticky md:top-(--plf-sticky-offset) md:self-start" aria-label="On this page"><!-- In-page links --></nav>
<main class="scroll-mt-(--plf-scroll-offset)" id="content" tabindex="-1"><!-- prose content with heading ids --></main>
</div>
</div>| Class | Behavior |
|---|---|
sticky top-0 z- |
A header that sticks to the top of its scroll container, above the content |
sticky top- |
Sticks below the header and does not stretch in a flex or grid row |
md: |
The same from that breakpoint up; below it the element scrolls normally |
scroll-mt- |
A link target stops 1rem below the header; headings with an id inside prose stop right below it on their own |
not-focus-within: |
Visually hidden until it or a descendant has focus; use it for skip links |
Utilities lists the display helpers, such as hidden md:flex, and every other utility.