Layout Grids skill for Codex

One spacing scale, edges that line up. Codex audits the margins and arbitrary spacing values already in the code, defines a 4 px based scale with proximity rules, and builds a page shell with full-bleed and content tracks from CSS Grid named lines. It adds stack, cluster, sidebar and switcher primitives, aligns card internals with subgrid, and checks alignment with a debug overlay.

  • Design & UX
  • $layout-grids
  • 205 lines
  • 2 files
  • ~1,900 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- layout-grids

Installs to ~/.agents/skills/layout-grids/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $layout-grids, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Sets up layout grids and spacing systems for web UI - a 4 px based spacing scale, column grids per breakpoint, content and full-bleed tracks with CSS Grid named lines, subgrid for aligned cards, stack, cluster and sidebar layout primitives, section rhythm and density modes, plus a grid overlay and an off-scale spacing audit. Use when spacing feels random, alignment drifts between sections, building a page shell or container system, defining gutters and max widths, or replacing magic-number margins with a scale.

Use it when

  • Spacing values are inconsistent or full of magic numbers
  • Building a page shell, container or column grid
  • Section edges and card contents do not line up
  • Adding compact and comfortable density modes

Use something else when

How to check the result

A grid overlay at 360, 768, 1024 and 1440 px shows aligned edges, there is no horizontal scroll at 320 px, and the spacing audit finds no off-scale values outside the allowlist.

The mistake it prevents

Spacing siblings with margins on the children instead of gap on the parent, which collapses unpredictably and breaks when components are reused.

~/.agents/skills/layout-grids/SKILL.md

--- name: layout-grids description: Sets up layout grids and spacing systems for web UI - a 4 px based spacing scale, column grids per breakpoint, content and full-bleed tracks with CSS… license: MIT ---

Layout is right when every gap comes from one scale, related things sit closer than unrelated things, edges line up across sections, and the grid adapts by changing column count and gutters rather than by squeezing content. Magic numbers (margin-top: 37px) are the symptom; a missing system is the cause.

Before changing anything

  • Read AGENTS.md and existing layout code: container components, Tailwind @theme spacing, global CSS, page shells.
  • Audit spacing values in use:
rg -o --glob '*.{css,scss}' '(margin|padding|gap)[a-z-]*:\s*[^;]+' src | rg -o '[0-9.]+(px|rem)' | sort | uniq -c | sort -nr | head -30
rg -o --glob '*.{tsx,jsx,vue,svelte,html}' '\b(p|m|gap|space)-[xytrbl]?-?\[[^\]]+\]' src | sort | uniq -c | sort -nr

The second command finds Tailwind arbitrary values, which are usually off-scale escapes.

Spacing scale

Use a 4 px base with a geometric feel at the top end:

TokenrempxTypical use
space-10.254Icon to label, tight inline
space-20.58Inside compact controls, between related lines
space-30.7512Control padding, list item gap
space-4116Default gap inside a group, card padding (compact)
space-61.524Card padding, gap between groups
space-8232Between components in a section
space-12348Between sub-sections
space-16464Section padding on mobile
space-24696Section padding on desktop
space-328128Hero and major breaks

Rules:

  • Proximity: the gap between groups is at least 1.5–2x the gap inside a group. If a label is as far from its input as from the previous field, the form reads as noise.
  • Padding inside a container is greater than or equal to the gap between its children.
  • Section padding scales with viewport: padding-block: clamp(4rem, 8vw, 8rem).
  • Tailwind v4 already uses a 0.25rem --spacing base (p-4 = 1rem); restrict the team to the steps above by convention or lint, and treat p-[13px] as a bug.

Column grid

ViewportColumnsGutterOuter margin
< 640 px416 px16–20 px
640–1023 px824 px32 px
≥ 1024 px1224–32 pxauto (centered container)

Container max width: 1200–1280 px for apps and marketing, 680–760 px for reading columns. Text never spans the full 12 columns on desktop; 6–8 columns is a readable measure.

Page shell with named lines

One grid gives full-bleed, wide and content tracks without wrapper divs:

.shell {
  --content: min(72rem, 100% - 2 * var(--margin));
  --margin: clamp(1rem, 4vw, 2rem);
  display: grid;
  grid-template-columns:
    [full-start] 1fr
    [wide-start] minmax(0, 6rem)
    [content-start] var(--content) [content-end]
    minmax(0, 6rem) [wide-end]
    1fr [full-end];
}
.shell > * { grid-column: content; }
.shell > .wide { grid-column: wide; }
.shell > .full { grid-column: full; }

Inner 12-column grid

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-6);
}
.span-7 { grid-column: span 7; }
.span-5 { grid-column: span 5; }
@media (width < 1024px) { .grid-12 > * { grid-column: 1 / -1; } }

Use minmax(0, 1fr), not 1fr: plain 1fr has an automatic minimum and long words or wide tables blow the column out.

Card grids

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

auto-fill keeps empty tracks so a single card does not stretch full width; use auto-fit when stretching is wanted. The min(18rem, 100%) prevents overflow on narrow screens. Subgrid is supported in all current evergreen browsers.

Layout primitives

Most layouts are compositions of four primitives; build these once:

PrimitiveCSS coreUse
Stackdisplay:flex; flex-direction:column; gap: var(--stack-gap, var(--space-4))Vertical flow of anything
Clusterdisplay:flex; flex-wrap:wrap; gap; align-items:centerTags, buttons, nav items
Sidebardisplay:flex; flex-wrap:wrap with sidebar flex-basis: 16rem and main flex: 999 1 30remContent with a side panel that drops below when narrow
Switcherflex-wrap:wrap; > * { flex-grow:1; flex-basis: calc((40rem - 100%) * 999) }Row of equal items that becomes a column below a threshold, no media query

Spacing between siblings comes from the parent’s gap, never from margins on children. Components own their internal padding, never their outer margin.

Vertical rhythm

  • Keep line heights and spacing on the 4 px grid where practical (16 px text at 1.5 = 24 px line). Perfect baseline grids are rarely worth the cost on the web.
  • Headings sit closer to the content they introduce than to the content above: margin-block: var(--space-12) var(--space-3) for an h2 in prose.
  • text-box: trim-both cap alphabetic trims the extra leading above caps and below baselines for exact optical spacing; support is recent, so treat it as a progressive enhancement.

Density modes

For data-heavy apps, define density via a multiplier rather than separate components:

:root { --density: 1; }
[data-density="compact"] { --density: 0.75; }
.cell { padding: calc(var(--space-2) * var(--density)) calc(var(--space-3) * var(--density)); }

Workflow

- [ ] 1. Audit current spacing values and containers
- [ ] 2. Define the scale and map existing values to it (table)
- [ ] 3. Build the page shell and primitives
- [ ] 4. Migrate sections; delete margins on children in favour of parent gap
- [ ] 5. Verify with the grid overlay at 360, 768, 1024, 1440 px

Debug overlay (dev only):

.debug-grid { position: relative; }
.debug-grid::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 9999;
  background: repeating-linear-gradient(to right,
    oklch(0.7 0.2 25 / .12) 0 calc((100% - 11 * var(--space-6)) / 12),
    transparent 0 calc((100% - 11 * var(--space-6)) / 12 + var(--space-6)));
}

Gotchas

  • Margin collapse between siblings and parent/child produces “random” gaps; flex and grid gaps do not collapse, which is another reason to prefer gap.
  • 100vw includes the scrollbar on desktop browsers and causes horizontal scroll; use the full-bleed grid track instead.
  • Fixed heights on cards cut content when copy or locale changes; use subgrid or align-items: stretch.
  • Different containers per page (1140, 1200, 1280) make edges jump during navigation. One container token.
  • Changing gap at breakpoints but not padding makes mobile layouts feel cramped inside and loose outside. Scale both.

Verification

  • Re-run the audit: off-scale values and arbitrary Tailwind spacing reduced to an agreed allowlist (ideally zero).
  • Overlay screenshots at each breakpoint: left edges of headings, text and cards align to columns; no horizontal scroll at 320 px.
  • Check one long-content case (long title, translated German copy) for overflow.

Output contract

**Scale:** 4 px base, tokens space-1..space-32 (file: ...)
**Grid:** 4/8/12 columns, gutters 16/24/32, container 72rem, reading 65ch
**Primitives:** Stack, Cluster, Sidebar, Switcher (path)
**Migration:** <n> off-scale values replaced, <n> child margins converted to gap
**Exceptions:** <allowlisted values and why>

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Layout Grids"
  short_description: "One spacing scale, edges that line up"
  default_prompt: "$layout-grids The spacing on our pages is all over the place, set up a proper spacing scale"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem