CSS Layout & Responsiveness
Modern CSS layouts: the box model, Flexbox for one dimension, Grid for two, media and container queries for responsiveness. Build layouts that adapt without a single line of JavaScript.
What is this?
CSS layout determines how boxes flow on a page. The box model computes each element's size from content, padding, border and margin. Flexbox arranges items along a single axis, Grid places items on two axes with explicit tracks, and media/container queries adapt the layout to the viewport or its container.
Why do you need it?
- Layout bugs are the most common source of CSS pain, so mastering the systems prevents whole classes of issues.
- Flexbox and Grid replaced table and float hacks with declarative, predictable alignment.
- Responsive layouts need no JavaScript, which keeps pages fast and resilient.
- Container queries make components responsive to their own context, not just the viewport.
- Logical properties let one stylesheet work in left-to-right and right-to-left languages.
Mental model
Grid paper vs a single conveyor belt
CSS Grid vs Flexbox
Grid paper positions anything at an exact row and column intersection; a conveyor belt only moves items along one line. Grid excels at two-dimensional page structure, Flexbox at laying out a row or column of items.
How it works
- Every element is a box sized by content plus padding, border and margin (the box model).
- Block boxes stack vertically in normal flow; inline boxes sit on the baseline of the text line.
- display: flex makes a container lay out children along a main axis, with the cross axis perpendicular.
- display: grid creates explicit tracks with grid-template-columns and places items by line or area.
- Media queries switch rules by viewport width, while container queries switch by the size of a named container.
Building a responsive two-column layout.
Key commands
npx serve .Serve the folder so layouts can be tested in a real browser.
Serving! Local: http://localhost:3000
npx stylelint '**/*.css'Lint for invalid properties, ordering and browser pitfalls.
npx prettier --write '**/*.css'Format stylesheets consistently.
npx postcss --use autoprefixer src/style.css -o dist/style.cssAdd vendor prefixes for older browsers.
npx lightningcss --minify src/style.css -o dist/style.cssMinify and transform modern CSS for target browsers.
Examples
A responsive dashboard grid
.dashboard { display: grid; grid-template-columns: 1fr; gap: 1rem;} @media (min-width: 768px) { .dashboard { grid-template-columns: repeat(2, 1fr); }} @media (min-width: 1024px) { .dashboard { grid-template-columns: repeat(3, 1fr); }} .card { padding: 1rem; border: 1px solid #e0e0e0; border-radius: 8px;} .toolbar { display: flex; gap: 0.5rem; justify-content: space-between; align-items: center;}Grid switches from one column on phones to two and three columns at successive breakpoints. The gap property spaces tracks. Flexbox lays the toolbar items along one axis with space-between, showing when each tool fits the layout.
In production
- Dashboards, admin consoles and media galleries are built on Grid with explicit track definitions.
- Navigation bars, button groups and toolbars are Flexbox: one axis, alignment and wrapping.
- Marketing pages use container queries so cards reflow based on their slot, not just the viewport.
- Email-safe layouts still lean on tables, but Flexbox and Grid cover virtually everything in the browser.
Best practices
- Write mobile-first: define the base layout for small screens, then widen with min-width media queries.
- Use gap instead of margins for spacing between grid and flex children.
- Prefer relative and fluid units (rem, %, fr, clamp) over fixed pixel widths.
- Use logical properties (margin-inline-start) so layouts flip correctly for RTL languages.
- Limit breakpoints to where the content breaks, not arbitrary device widths.
Common mistakes
- Setting fixed pixel widths so content overflows on smaller viewports.
- Reaching for media queries when Flexbox wrap or Grid's auto-fit would adapt automatically.
- Using float and clear hacks that Flexbox and Grid have long replaced.
- Forgetting min-width: 0 or overflow on grid/flex children, causing content to blow out the track.
Common issues
Content overflows the viewport horizontallyA fixed-width element, long unbreakable string, or grid child without min-width: 0.
Switch to fluid units, add overflow-wrap: anywhere on text, and set min-width: 0 on grid children.
Items do not wrap in a flex rowflex-wrap defaults to nowrap.
Add flex-wrap: wrap and give items a basis such as flex: 1 1 240px.
A media query has no effectThe query is declared before the base rules it must override, or the syntax has a typo.
Declare overrides after the base rules and check the media query syntax.
Debugging tips
- Toggle outline: 1px solid red on all elements to see every box and its boundaries.
- Use DevTools' Layout panel to visualize grid tracks and flex lines on hover.
- Inspect the Computed tab to see which box-model sizes actually applied versus expected.
- Test layout at several widths in device emulation to find where content first overflows.
Interview checkpoint
Hands-on lab
- Structure a dashboard with semantic HTML
- Use Grid for the main layout
- Use Flexbox for toolbars
- Make the layout responsive with media queries
Build a Responsive Dashboard Layout
30 min ยท intermediate
Quick quiz
Which CSS property defines the columns of a grid container?
Media queries can only target the viewport width.
What is the default value of flex-wrap?
Cheat sheet
display: flexOne-dimensional row/column layoutjustify-contentAlign along the main axisalign-itemsAlign along the cross axisflex: 1 1 0Grow, shrink, basis shorthandgap: 1remSpace between itemsdisplay: gridTwo-dimensional layoutgrid-template-columns: 1fr 1frDefine column tracksgrid-column: 1 / 3Span columns by linerepeat(auto-fit, minmax(200px, 1fr))Auto responsive tracksgrid-areaName a region for placement