Modern Layouts
Modern CSS layout combines Grid and Flexbox with intrinsic sizing tools like minmax() , clamp() , and auto-fit to build layouts that respond to their content and container automatically, often with no media queries at all.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll build responsive layouts that adapt themselves — a card grid that reflows from many columns to one with no media queries, fluid sizes that scale with the screen, media boxes that never jump, and perfect centring in a single line — by combining CSS Grid and Flexbox the way modern sites actually do.
Modern layout is like a smart bookshelf, not a fixed display case. An old fixed layout is a glass case built for exactly six items at exactly one width — add a seventh or shrink the room and it breaks. Grid and Flexbox give you an adjustable shelf instead: you say "each book needs at least 250mm, and never let one fall below that," and the shelf decides how many fit per row as the room changes size.
minmax() is the "at least this wide" rule, auto-fit is the shelf counting how many fit, and clamp() is a label that grows with the shelf but never gets silly-big or unreadably small. You describe the intent once; the browser does the rearranging — that is what "intrinsic, responsive layout" means.
Most sizes you write are extrinsic — a number you picked, like width: 300px . Intrinsic sizing instead lets the content set the size. Three keywords do the work: min-content is the narrowest a box can be without its text overflowing (roughly the longest single word), max-content is as wide as the content wants if it never wrapped, and fit-content sits between the two: shrink to the content, but cap at the available space.
Run the worked example. Each box has the same text but a different sizing keyword, so you can see how the box hugs, expands, or caps itself based on the content — no pixel widths anywhere.
clamp(min, preferred, max) returns a value that scales with the viewport but never crosses two limits. The middle argument usually contains a viewport unit like vw (1vw = 1% of the viewport width), so the value grows as the screen grows — until it would dip below the min or rise above the max , where it locks. One line of clamp() replaces a whole stack of breakpoints.
It shines for fluid typography ( font-size: clamp(1.5rem, 4vw, 3rem) ) and fluid container widths . The text or box resizes smoothly across every screen size instead of jumping at fixed breakpoints.
This is the headline technique. Instead of telling Grid how many columns you want, you describe the shape of one column and let the browser fit as many as it can: grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) . Read it as: "make as many columns as fit, each at least 250px wide, and let them grow to share the leftover space equally ( 1fr )."
As the screen narrows, fewer columns fit, so the grid drops from four to three to two to one — all by itself, with not a single media query . auto-fit collapses any empty tracks so your cards always stretch to fill the row; its sibling auto-fill keeps those empty tracks (covered in the FAQ). This is the worked example to study closely — the two "Your Turn" exercises build straight on it.
When an image or video has a known width but its height arrives only once it loads, the page jumps as the box suddenly grows — that visible shift is "cumulative layout shift", and it hurts both the reader and your Core Web Vitals score. aspect-ratio: 16 / 9 fixes it by computing the height from the ratio and the known width before anything loads, so the slot is the right size from the start.
Set the width (or let the grid set it) and leave the height automatic — the browser fills in the missing dimension from the ratio. Pair it with an img using object-fit: cover so the picture fills the slot without distorting.
Centring on both axes used to need margin hacks or absolute positioning with transforms. Now, on any grid or flex container, one declaration does it: display: grid; place-items: center; . place-items is shorthand for align-items (the block / vertical axis) and justify-items (the inline / horizontal axis) at once, so center means dead-centre with no knowledge of the child's size.
The same trick works in Flexbox with display: flex; align-items: center; justify-content: center; . Use place-content instead when you want to centre the whole group of tracks rather than each item inside its cell.
The cards below are stacked because the grid line is missing. Fill in the blanks marked ___ to turn this into a responsive grid that reflows on its own, then run it and check the expected result in the comments.
Pull three of this lesson's tools together: give the heading a fluid size with clamp() , lock each tile to a 4:3 shape with aspect-ratio , and centre the label inside with place-items . Fill in the blanks, then verify against the comments.
Support is faded now — only an outline is given. Build a small "Our Features" section that combines everything: a fluid heading, a self-reflowing card grid, fixed-ratio thumbnails, and a centred label. Use the worked examples in sections 2–5 as your reference if you get stuck.
You can now build layouts that adapt themselves instead of being pinned to fixed pixels. The essentials:
Next up: Complex Tables , where you'll present structured data with accessible, responsive table markup.
Practice quiz
Which one-line value builds a responsive card grid that reflows with no media queries?
- grid-template-columns: repeat(4, 1fr)
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))
- grid-template-columns: auto auto auto
- grid-template-columns: 100%
Answer: grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)). repeat(auto-fit, minmax(250px, 1fr)) makes as many columns as fit, each at least 250px and growing to share the row.
What does the in do?
- Locks the column at 250px
- Lets the column grow to an equal share of leftover space
- Sets a 1px minimum
- Adds a 1rem gap
Answer: Lets the column grow to an equal share of leftover space. fr is a fraction of leftover space, so 1fr lets each column grow past 250px to share the row equally.
What is the difference between and ?
- They are identical
- auto-fit collapses empty tracks so items stretch; auto-fill keeps empty tracks
- auto-fill collapses empty tracks; auto-fit keeps them
- auto-fit only works in Flexbox
Answer: auto-fit collapses empty tracks so items stretch; auto-fill keeps empty tracks. auto-fit collapses empty tracks so existing items stretch to fill the row; auto-fill keeps the empty tracks.
What is the correct argument order for ?
- clamp(preferred, min, max)
- clamp(max, preferred, min)
- clamp(min, preferred, max)
- clamp(min, max, preferred)
Answer: clamp(min, preferred, max). clamp() takes the minimum first, the preferred (often viewport-based) value second, and the maximum last.
Which intrinsic keyword sizes a box to the narrowest it can be without overflow (roughly the longest word)?
- max-content
- fit-content
- min-content
- auto
Answer: min-content. min-content is the narrowest a box can be without its content overflowing — about the longest single word.
Which property reserves a media slot's height before the file loads to prevent layout shift?
- object-fit
- aspect-ratio
- min-height
- content-visibility
Answer: aspect-ratio. aspect-ratio (e.g. 16 / 9) computes the height from the known width up front, stopping cumulative layout shift.
For to supply the height, what should you avoid setting?
- The width
- An explicit height
- A background color
- A border-radius
Answer: An explicit height. An explicit height overrides aspect-ratio; set only the width and leave height automatic so the ratio fills it in.
Which one line centers a child on both axes in a grid container?
- text-align: center
- place-items: center
- margin: auto
- vertical-align: middle
Answer: place-items: center. On a grid (or flex) container, place-items: center centers items on both axes; it is shorthand for align-items and justify-items.
only works when the parent has which display value?
- block
- inline
- grid or flex
- table
Answer: grid or flex. place-items only takes effect on a grid or flex container; on a plain block it has no effect.
Which use scales a heading fluidly between two sizes?
- font-size: clamp(1.5rem, 4vw, 3rem)
- font-size: clamp(3rem, 4vw, 1.5rem)
- font-size: clamp(4vw)
- font-size: clamp(1.5rem, 3rem)
Answer: font-size: clamp(1.5rem, 4vw, 3rem). clamp(1.5rem, 4vw, 3rem) scales with the viewport but never drops below 1.5rem or exceeds 3rem.