Design & UX No. 361

Responsive Layouts skill for Claude Code

Layouts that fit the content, not a device list. Claude builds layouts that reflow on their own using minmax, auto-fill and flex-wrap recipes, saves media queries for genuine page-level changes, and makes reusable components respond to their container rather than the viewport. It also handles the mobile traps that ship broken: 100vh overflow, notches, iOS input zoom and flex children that refuse to shrink.

  • nameresponsive-layouts
  • size166 lines · ≈1,900 tokens
  • files1
  • licenseMIT
  • updated

What Claude sees before loading it

This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.

description: Builds layouts that adapt by content rather than device lists — mobile-first CSS Grid and Flexbox recipes, intrinsic patterns (stack, cluster, sidebar, switcher), container queries for reusable components, content-driven breakpoints, fluid spacing, dvh and safe-area handling, and subgrid alignment. Use when a page breaks at some width, building a page shell or card grid, making a component work in sidebars and main columns, or replacing a pile of media queries.

Try asking

  • This page scrolls horizontally on mobile. Find the cause and fix the layout
  • Make this card component work in both the sidebar and the main column
  • Rebuild our page shell so text stays readable but images can go full width

Use it when

  • A page breaks or overflows at certain widths
  • Building a page shell, card grid, or sidebar layout
  • A component must adapt to different containers
  • Too many media queries are fighting each other

Skip it when

  • You need cascade layers, naming and specificity strategy, use css-architecture instead
  • You are implementing a specific Figma frame pixel by pixel, use figma-to-code instead

How to check the result

A continuous 320 to 1920 pixel sweep shows no overlap or horizontal scroll, and 400% zoom at 1280 pixels reflows into a single readable column.

The common mistake it prevents

Forgetting min-width: 0 on flex and grid children, so one long URL or code line pushes the whole page into horizontal scroll.

~/.claude/skills/responsive-layouts/SKILL.md

--- name: responsive-layouts description: Builds layouts that adapt by content rather than device lists — mobile-first CSS Grid and Flexbox recipes, intrinsic patterns (stack,… license: MIT ---

A layout is done when it works at every width from 320px to 1920px+ (not just at three device sizes), components adapt to the space they are given rather than the viewport, nothing scrolls horizontally, and the code has few breakpoints because intrinsic sizing does most of the work.

Ground rules

  • Mobile-first: base styles are the narrow layout; min-width queries add complexity.
  • Breakpoints come from content. Drag the viewport until the design breaks; that width is the breakpoint. Device widths are a test list, not a design input.
  • Prefer intrinsic sizing (minmax, auto-fit, flex-wrap, min(), clamp()) over queries. A layout with 15 media queries is fighting the browser.
  • Component-level adaptation uses container queries; page-level uses media queries.
  • Use logical properties (margin-inline, padding-block, inset-inline-start) so RTL works for free.

Avoid the generic look

Default reflexBetter
Everything centered in a 1200px columnMix measures: text at 65ch, media breaking wider, full-bleed bands for rhythm
Uniform 3-column card grid for every listVary emphasis: a 2:1 feature split, a 7/5 asymmetric grid, a lead item spanning two columns
Same 64px vertical padding on every sectionSection spacing on a scale (64 / 96 / 128) chosen by the section’s importance
Hero = left text, right image, at every breakpointDecide the mobile order deliberately (often visual after headline, before body)
Fixed px guttersFluid gutters: clamp(1rem, 4vw, 3rem)

Workflow

- [ ] 1. Sketch the narrow layout and the wide layout; note what changes between
- [ ] 2. Build the page shell (gutters, max widths, full-bleed escape)
- [ ] 3. Lay out sections with intrinsic grids/flex first
- [ ] 4. Make reusable components container-aware
- [ ] 5. Add the few media queries content still needs
- [ ] 6. Test the sweep: 320 → 1920, zoom 200%, landscape phone

2. Page shell with full-bleed escape

.page {
  --gutter: clamp(1rem, 4vw, 3rem);
  --content: 68ch;
  --wide: 75rem;
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, calc((var(--wide) - var(--content)) / 2))
    [content-start] min(var(--content), 100% - 2 * var(--gutter)) [content-end]
    minmax(0, calc((var(--wide) - var(--content)) / 2)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
}
.page > * { grid-column: content; }
.page > .wide { grid-column: wide; }
.page > .full { grid-column: full; }

3. Intrinsic recipes (no media queries)

NeedRecipe
Card grid that reflowsgrid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
Vertical rhythm.stack > * + * { margin-block-start: var(--space, 1rem); } or display:flex; flex-direction:column; gap
Inline group that wraps (tags, buttons)display:flex; flex-wrap:wrap; gap:.5rem; align-items:center;
Sidebar + main that stacks when narrow.with-sidebar{display:flex;flex-wrap:wrap;gap:2rem} .sidebar{flex-basis:18rem;flex-grow:1} .main{flex-basis:0;flex-grow:999;min-inline-size:60%}
Row that becomes column below a widthSwitcher: .switcher{display:flex;flex-wrap:wrap;gap:1rem} .switcher>*{flex-grow:1;flex-basis:calc((40rem - 100%) * 999)}
Fluid spacingpadding-block: clamp(3rem, 8vw, 8rem);

auto-fill keeps empty tracks (items stay card-sized); auto-fit collapses them (items stretch to fill). Use auto-fill when a lone item stretching full width would look odd.

min(100%, 16rem) in minmax prevents overflow on screens narrower than the minimum.

4. Container queries for components

.card-list { container-type: inline-size; container-name: cards; }

.card { display: grid; gap: 0.75rem; }
@container cards (min-width: 36rem) {
  .card { grid-template-columns: 12rem 1fr; align-items: start; }
}
.card h3 { font-size: clamp(1.1rem, 3.5cqi, 1.5rem); }   /* container-relative units */
  • container-type: inline-size on the parent, never on the element you query from inside (an element cannot query itself).
  • Inline-size containment means the container cannot size to its content’s width; it must get width from its parent (block-level or a grid track).
  • Supported in all evergreen browsers since 2023; style queries are less supported, so do not rely on them for core layout.

5. Media queries that remain

Use them for page-level changes: navigation pattern, number of page columns, hero arrangement. Write them in rem/em so they respond to user font size, and use range syntax:

@media (width >= 48rem) { .site-nav { display: flex; } .nav-toggle { display: none; } }

Align subcomponents across cards with subgrid:

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); gap: 1.5rem; }
.card  { display: grid; grid-row: span 3; grid-template-rows: subgrid; }  /* title, body, footer align across cards */

Mobile specifics

  • Viewport units: use 100dvh for full-height panels (adapts to browser chrome), 100svh when you need the smallest stable height (no jump on scroll). Plain 100vh overflows behind mobile toolbars.
  • Notches: add viewport-fit=cover to the viewport meta only if you then pad with env(safe-area-inset-*), e.g. padding-bottom: max(1rem, env(safe-area-inset-bottom)).
  • Touch targets ≥ 24×24 CSS px (WCAG 2.2 AA), aim for 44×44 on primary actions, with ≥ 8px between adjacent targets.
  • Never disable zoom (user-scalable=no, maximum-scale=1).
  • Inputs with font-size below 16px trigger iOS zoom on focus.
  • Hover-only affordances need a tap path: gate hover effects with @media (hover: hover) and (pointer: fine).

Gotchas

  • Flex/grid children default to min-width: auto and refuse to shrink below their content: long URLs or code blocks cause horizontal scroll. Add min-width: 0 to the flex/grid child, and overflow-wrap: anywhere to user content.
  • width: 100vw includes the scrollbar on desktop and causes horizontal scroll; use the full-bleed grid column or width: 100%.
  • Images need max-width: 100%; height: auto; plus width/height attributes to reserve space (CLS).
  • Tables: wrap in a scroll container with a visible affordance, or reflow rows into cards below a container width.
  • Reordering with order or grid-area changes visual but not tab/reading order; keep DOM order meaningful (WCAG 1.3.2, 2.4.3).
  • Fixed headers eat small-landscape screens; keep them ≤ 56px or hide on scroll down.

Verification

  • Sweep: in DevTools responsive mode, drag width continuously from 320 to 1920 and watch for overlaps, orphaned items, and line lengths over 80ch.
  • Check horizontal overflow programmatically in the console: [...document.querySelectorAll('*')].filter(e => e.scrollWidth > document.documentElement.clientWidth).
  • Test at 1280px with 200% and 400% zoom (400% ≈ 320px reflow, WCAG 1.4.10).
  • Test a real phone in portrait and landscape, with the on-screen keyboard open on forms.
  • Playwright screenshots at 375, 768, 1024, 1440 for regressions (see visual-regression).

Output contract

## Layout notes
Shell: content 68ch / wide 75rem / full-bleed; gutter clamp(1rem, 4vw, 3rem)
Breakpoints (content-derived): 48rem nav switch, 64rem 2-col article
Container-aware components: Card (36rem), ProductTile (28rem)
Tested: 320–1920 sweep, 200%/400% zoom, iOS Safari portrait/landscape

About this skill

Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.

esc