Fluid layouts use relative units and flexible containers so content adapts smoothly to any screen size — not just at specific breakpoints, but at every pixel in between.
Percentage-Based Widths
The simplest fluid technique replaces fixed pixel widths with percentages:
/* Fixed: breaks on small screens */
.container {
width: 960px;
}
/* Fluid: adapts to any screen */
.container {
width: 100%;
max-width: 960px;
margin: 0 auto;
padding: 0 1rem;
}The max-width pattern is essential. It lets the container shrink below 960px on small screens while capping it at 960px on large screens. The padding ensures content never touches the screen edges on mobile.
Flexbox for Fluid Rows
Flexbox is ideal for single-axis fluid layouts. Items grow and shrink based on available space:
.card-row {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 300px;
}The flex: 1 1 300px shorthand means: grow to fill space, shrink if needed, with a base size of 300px. Combined with flex-wrap, cards automatically wrap to the next row when the container is too narrow — no media queries needed.
<div class="card-row">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
</div>On a 1200px screen, all three cards fit in one row. On a 600px screen, they wrap into a column. The layout responds to space, not to device width.
CSS Grid for Two-Dimensional Layouts
CSS Grid's auto-fit and minmax() create fluid grids without any media queries:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}This tells the browser: create as many columns as fit, where each column is at least 250px wide and stretches to fill remaining space equally. As the viewport shrinks, columns drop off naturally.
For asymmetric layouts, use fractional units:
.layout {
display: grid;
grid-template-columns: 1fr 3fr;
gap: 2rem;
}
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
}
}The clamp() Function
clamp() sets a value that scales between a minimum and maximum:
.container {
width: clamp(320px, 90%, 1200px);
}This reads as: the width is 90% of the parent, but never less than 320px and never more than 1200px. One line replaces a width, min-width, and max-width declaration.
clamp() shines for spacing too:
section {
padding: clamp(1rem, 4vw, 4rem);
}On small screens, padding is at least 1rem. On large screens, it caps at 4rem. In between, it scales fluidly with the viewport.
Fluid Typography
Fixed font sizes create jarring jumps at breakpoints. Fluid typography scales smoothly:
h1 {
font-size: clamp(1.75rem, 4vw + 0.5rem, 3.5rem);
}
p {
font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
}The formula Xvw + Yrem combines viewport-relative scaling with a fixed base. The vw unit makes it fluid, while the rem addition ensures text remains readable on very small screens.
Best practices for fluid typography:
- Minimum size — never let body text go below 1rem (16px)
- Maximum size — cap headings to prevent absurdly large text on ultrawide monitors
- Line length — keep paragraphs at 45-75 characters per line for readability. Use
max-width: 65chon text containers
Fluid Spacing Scale
Apply the same fluid principle to your spacing system:
:root {
--space-xs: clamp(0.25rem, 0.5vw, 0.5rem);
--space-sm: clamp(0.5rem, 1vw, 1rem);
--space-md: clamp(1rem, 2vw, 2rem);
--space-lg: clamp(2rem, 4vw, 4rem);
--space-xl: clamp(3rem, 6vw, 6rem);
}Using CSS custom properties for your fluid spacing scale keeps your entire design system consistent and easy to adjust.
Key Takeaway
The goal of fluid layouts is to eliminate the gap between breakpoints. Instead of snapping between fixed layouts, your design flows smoothly across every possible screen width.