Responsive layout
Have Agents implement layout from project breakpoints, container width, and a mobile-first strategy, covering landscape, foldables, and comfortable reading width on large screens.
The SKILL should list standard breakpoints (px or rem), max content width (measure), sidebar collapse rules, and whether @container wraps card grids; acceptance must cover typical device widths and minimum height, not desktop-only viewports.
Align with the CSS architecture skill: layout class naming, utilities vs component responsibility; if print or PDF export exists, add media-type rules beyond breakpoints.
- Acceptance checklist: key pages at typical widths + min height via screenshots or a Story viewport matrix.
- For landscape / fold inner–outer screens when relevant, document whether breakpoints or container strategy tie to “unfolded width.”
Breakpoint System and Mobile-First Media Queries
/* Breakpoint system: CSS variables (kept in sync with Design Tokens) */
:root {
--bp-sm: 36rem; /* 576px - phone landscape */
--bp-md: 48rem; /* 768px - tablet */
--bp-lg: 64rem; /* 1024px - small desktop */
--bp-xl: 80rem; /* 1280px - large desktop */
--content-max-width: 72rem; /* max content width */
}
/* Mobile-first: base styles target the narrowest viewport; min-width adds progressively */
.card-grid {
display: grid;
grid-template-columns: 1fr; /* base: single column */
gap: var(--space-4);
}
@media (min-width: 48rem) { /* md: two columns */
.card-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 64rem) { /* lg: three columns */
.card-grid { grid-template-columns: repeat(3, 1fr); }
}
/* Desktop-first (for comparison — not recommended for new projects) */
/* .card-grid { grid-template-columns: repeat(3, 1fr); } */
/* @media (max-width: 64rem) { grid-template-columns: 1fr 1fr; } */
/* clamp() fluid typography: min / preferred / max */
h1 { font-size: clamp(1.5rem, 4vw + 0.5rem, 3rem); } /* 24px → 48px fluid */
p { font-size: clamp(1rem, 1vw + 0.75rem, 1.25rem); }
.container { padding-inline: clamp(1rem, 5vw, 3rem); } /* responsive padding */
The table below is a sample convention (replace with your design system):
| Band | Viewport (sample) | Typical use |
|---|---|---|
| base | < 36rem | Single column, full-width actions, collapsed nav |
| md | ≥ 48rem | Two-column summaries, sidebar can appear |
| lg | ≥ 64rem | Three-column grid, fixed sidebar width |
| xl | ≥ 80rem | Max content width + margins, large-screen whitespace |
Container Queries and Grid+Flexbox Combination Layout
/* Container Query: component width determined by parent, not viewport */
.sidebar-widget {
container-type: inline-size;
container-name: widget; /* named container: enables targeted queries */
}
/* @container: same component adapts in narrow sidebar vs wide main area */
.widget-grid {
display: grid;
grid-template-columns: 1fr; /* default: single column */
}
@container widget (min-width: 28rem) {
.widget-grid { grid-template-columns: 1fr 1fr; }
}
@container widget (min-width: 44rem) {
.widget-grid { grid-template-columns: repeat(3, 1fr); }
}
/* @supports fallback for browsers that don't support container queries */
@supports not (container-type: inline-size) {
.widget-grid { grid-template-columns: 1fr 1fr; }
}
/* Grid + Flexbox combination layout */
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr; /* fixed sidebar + flexible main area */
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* Use Flexbox inside main area for content flow */
.page-main {
grid-area: main;
display: flex;
flex-direction: column;
gap: var(--space-6);
padding: var(--space-6);
}
/* Mobile: collapse sidebar */
@media (max-width: 48rem) {
.page-layout {
grid-template-areas: "header" "main" "footer";
grid-template-columns: 1fr;
}
.page-sidebar { display: none; } /* or use transform for slide-in */
}
Document container names (container-name), query thresholds, and fallbacks: single-column when container queries are unsupported, or approximate layout via @supports.
Layout decision flow
[ Design / grid contract ]
│
▼
┌─────────────┐ Root typography: clamp / rem, max-width (measure)
│ Fluid & measure │── safe area, viewport-fit, landscape min height
└─────────────┘
│
▼
┌─────────────┐ Nav / full-page split / theme: @media (min-width …)
│ Viewport BP │── mobile-first order, tokens aligned with design
└─────────────┘
│
▼
┌─────────────┐ Cards / toolbars / modules in rails: container + @container
│ Container Q │── names, thresholds, no-support single-column fallback
└─────────────┘
│
▼
┌─────────────┐ srcset/sizes, table scroll or stack, touch targets ≥ 44×44 CSS px
│ Media & Ix │── foldables, keyboard focus, prefers-reduced-motion
└─────────────┘
│
▼
[ Viewport matrix screenshots / Story multi-viewport + key container widths ]
Media, tables, and touch
Specify srcset/sizes or CSS object-fit strategies so small screens do not download oversized assets; document horizontal scroll for wide tables (overflow-x, sticky header strategy) or stacked layouts on narrow viewports.
Call out minimum touch target size, safe areas (notch), and viewport-fit when relevant; review animation downgrades with prefers-reduced-motion.
In-page demo: viewport band and container width
The script below runs only on this page: the readout shows current viewport width and a sample breakpoint band; drag the slider to change the query container width and watch columns switch at @container (min-width: 22rem).
SKILL outline
---
name: responsive-layout
description: Implement consistent cross-device layout from breakpoints and container strategy
---
# Breakpoint system
1. Define breakpoints as CSS variables: --bp-sm/md/lg/xl, kept in sync with Design Tokens
2. Mobile-first: base styles target the narrowest viewport; enhance with min-width progressively (do not override with max-width)
3. Max content width (--content-max-width) defined centrally; avoid scattering it across individual components
# Fluid typography and spacing
4. clamp() fluid font sizes: clamp(min, preferred-vw-calc, max) covering headings, body, and padding
5. Fluid spacing: use clamp() or space tokens for padding/gap; avoid hard cuts at breakpoints
# Layout choices
6. Page-level columns / nav / overlays: @media min-width viewport breakpoints
7. Component-internal column count / density (cards / tables / toolbars): container-type + @container
8. Container naming (container-name): use business-semantic names for targeted @container queries
9. Grid: two-dimensional layout (page-layout); Flexbox: one-dimensional content flow (toolbars / lists)
# Compatibility and acceptance
10. @container without browser support: use @supports to provide single-column / two-column fallback
11. Touch targets: minimum 44×44 CSS px; the touch area may be larger than the visual size via padding
12. Landscape / foldables: document minimum-height strategy and whether unfolded width affects breakpoints
13. srcset/sizes: provide appropriate resolution per breakpoint; prevent small screens from loading large images
14. Reduced motion: use prefers-reduced-motion to downgrade animations
15. Acceptance matrix: screenshots at 375/768/1280/1920 width × portrait/landscape