Layout and spacing skill.

A free skill that teaches Claude Code, Codex, Cursor and other AI coding agents to space and align UI on purpose: a 4px spacing scale, grouping by distance, grids and layouts that hold from a 320px phone to a wide desktop.

Random spacing is the quickest way to make a page feel unfinished. This skill gives your agent one spacing scale and the reason behind each step, so it groups related things tightly, separates groups clearly and stops inventing values like 13px. It ends with a short checklist the agent runs before it hands the work back.

Skill
wensity-layout
Plan
Free, no account needed
Loads when
Building a page, section, form or dashboard, or changing spacing, grids or responsive layout
Works in
Claude Code, Codex, Cursor, GitHub Copilot, Windsurf, Gemini CLI, OpenCode
Format
Agent Skills (SKILL.md), plain files in your project

Install

Run this in your project. It finds the agents you use and puts the skill where each one looks for it.

terminal
pnpm dlx skills add wensity/skills --skill wensity-layout
wensity/skills

Open source under MIT, with the other free skills. A star helps other developers find them.

Star on GitHub

Or add it by hand: save the file as SKILL.md in a folder named wensity-layout.

Where each agent looks for it
Claude Code
.claude/skills/wensity-layout/SKILL.md
Codex, Cursor, Copilot, Windsurf, Gemini CLI, OpenCode
.agents/skills/wensity-layout/SKILL.md

When it loads

You never call a skill by name. Your agent reads the short description at the top of every installed skill and loads this one when the work calls for it. Requests like these bring it in:

  • This dashboard feels cramped and breaks on phones. Fix the layout and spacing.
  • The spacing on the pricing section looks random.
  • Make this settings page work on mobile.

What it covers

The spacing scale
One 4px scale where each step has a job, so values like 13px never show up.
Grouping and rhythm
Related things sit close and groups sit apart, with more space above a heading than below it, and sections that do not all share one gap.
Alignment and containers
One start edge per section, numbers aligned at the end, gutters that grow with the screen and text that never runs full width.
Grids
Card grids that fill the space they get, tracks allowed to shrink, bento grids with one gap, and subgrid for rows of cards.
Responsive structure
Breakpoints set by the content, layouts that restructure instead of shrinking, container queries, dvh units and safe areas.
Tables, density and touch
Row heights by density, sticky headers, wide tables that scroll in their own frame, and 44px touch targets.

Group a settings form by distance

One settings page, same fields, type and colours. Without the skill one gap does every job; with it each gap comes from the scale by job. Flip the switch, then drag the slider to see what the space between sections does.

16px

Profile

Shown on your comments, invoices and shared projects.

Notifications

Sent to maya@northwind.studio. Mentions also show in the app.

When someone tags you or answers your comment.

Every Monday at 9:00: hours logged and payments due.

Delete workspace

Removes Northwind Studio and its 14 projects for everyone on the team. This can't be undone.

Without the skill: One 16px gap does every job, so each label sits as close to the field above it as to its own input, and the three sections run together.

Key rules

Space before boxes
Group with distance first. A border or divider comes in only when space is not enough.
gap for siblings
Spacing between children is set once with gap on the parent, not with margins on each child.
Restructure, do not shrink
A three-column grid becomes a stack on phones, never three tiny columns.
No horizontal page scroll
Every layout is checked at 320px wide.
44px touch targets
Anything tappable gets a 44 by 44px hit area, even when it looks smaller.
dvh, not vh
Full-height sections use min-h-dvh so mobile browser bars do not cut them off.

Resize from desktop to phone

Drag the edge of the frame, or focus it and use the arrow keys, to take one store dashboard from 1280px down to 320px. With the skill the layout restructures one step at a time instead of squeezing.

390pxphone. Drag the edge of the frame.

Overview

Last 30 days, all channels

Revenue this month

$18,420

Orders awaiting shipment

27

Returning customers

41%

Restock the Field headphones

Nine pairs left at the current pace of four a day. The supplier needs eleven days, so order this week to avoid a gap.

Matte black over-ear headphones

Recent orders

OrderCustomerStatusTotal
#4821Aisha MensahShipped$249.00
#4820Tomás HerreraPacking$89.00
#4819Lena FischerShipped$1,120.00

Without the skill: At 390px nothing restructures: the sidebar keeps its 200px and each stat column is about 42px wide, so labels break mid-word.

The full skill

This is the whole skill, exactly as your agent reads it. Change anything you like once it is in your project: it is a plain file.

Layout is how a page tells people what matters and what belongs together, before they read a word. Good layout comes from three habits: a fixed spacing scale, grouping by distance, and one alignment system. This skill sets all three up and covers responsive structure.

If the project already has a spacing scale and container widths, use them.

1. The spacing scale

Use a 4px base. Every margin, padding and gap comes from this list:

TokenpxTypical use
14icon to label, tight inline gaps
28inside a control, between a label and its input
312between items in a dense list, button padding y
416card padding (compact), gap between related controls, mobile page gutter
520button padding x (large)
624card padding, gap between form fields
832between groups inside a section
1040between a section heading and its content (large)
1248section padding on mobile
1664between sections in an app, section padding on tablet
2080
2496section padding on desktop marketing pages
32128hero padding, the space around one big statement

Tailwind's default scale already follows a 4px base (p-4 is 16px), so use its steps and do not invent p-[13px]. Odd values are allowed only for optical corrections you checked in the render (an icon that looks off by 1px).

2. Group by distance

The single most important layout rule: space inside a group is smaller than space between groups. A label sits 8px from its input; the next field sits 24px away. A card's title sits 8px above its text; the next card sits 24px away. When inner and outer spacing are equal, everything floats apart and nothing reads as a group.

  • Aim for a ratio of about 1 to 2 or 1 to 3 between inner and outer gaps.
  • More space above a heading than below it. The heading belongs to the content after it. Typical: 48px above a section heading, 16px below.
  • Spacing before boxes. Group with distance first. Add a border, divider or background only when distance is not enough (dense tables, toolbars, content on busy backgrounds). A box around every group makes a page heavy.
  • Use gap for siblings (flex gap-4, grid gap-6) instead of margins on children. It keeps spacing in one place and avoids stray margin at the ends of a list.

3. Rhythm, not sameness

A page where every section has 96px padding, a centered heading and a grid of three items has no rhythm. Vary density on purpose:

  • Alternate dense sections (feature grids, tables, logos) with open ones (one statement, one large image).
  • Let important sections take more space. Space is how you spend attention.
  • Repeat a layout only when the content is truly the same kind of thing.

4. Alignment

  • One start edge. Headings, paragraphs, buttons and images in a section share the same starting line. Most "something looks off" complaints are two edges a few pixels apart.
  • Align to the start by default (text-align: start, which is left in English and right in Arabic or Hebrew). Center only short, standalone content: a hero headline, a single CTA block, an empty state. Forms, tables, lists and long text align to the start.
  • Align numbers to the end in tables and stat columns.
  • Align to text, not boxes. An icon next to a label aligns with the label's cap height or center, not the top of the line box. In flex rows, items-center for single lines; items-start plus a small top margin on the icon for multi-line text.
  • Optical adjustments: play icons, arrows and round shapes look off center when centered mathematically. Nudge by 1 to 2px after you see it.

5. Containers and widths

ContainerMax widthUse
Prose65ch (about 640 to 720px)articles, docs, long paragraphs
Narrow560 to 640pxforms, sign-in, focused tasks, a centered hero statement
Content1120 to 1280pxmost marketing sections and app pages
Wide1440 to 1600pxdashboards, galleries, editors
Full bleed100%backgrounds, images, product shots that should touch the edges
  • Page gutter: 16px on phones, 24px on tablets, 32 to 48px on desktop. Keep it consistent: one gutter value per breakpoint for the whole site.
  • Separate background from content width. A section's background can run full bleed while its content stays in the content container.
  • Do not let text run full width on wide screens. Images and grids can grow; paragraphs cannot.

6. Grids

  • 12 columns for marketing layouts gives you halves, thirds, quarters and asymmetric splits (7 and 5, 8 and 4). Asymmetric splits look more designed than 6 and 6.
  • Auto-filling grids for cards so the column count follows the space:
Source
.cards { display: grid; gap: 24px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }

The min(100%, 280px) stops overflow on screens narrower than 280px. auto-fill keeps card width steady when there are only one or two cards; auto-fit stretches the few cards to fill the row. Pick on purpose.

  • Let flexible tracks shrink. Grid and flex children refuse to shrink below their content by default, which is why long text or a wide table overflows a dashboard. Use minmax(0, 1fr) for flexible tracks and min-width: 0 (Tailwind min-w-0) on flex children that hold text:
Source
.app-shell { display: grid; grid-template-columns: 16rem minmax(0, 1fr); }
.row > .text { min-width: 0; }
  • Equal heights only for equal content. Cards in one row stretch to the tallest by default in grid. Fine for a set of plans; wrong when one card is clearly the featured one.
  • Bento grids: vary tile sizes by importance, keep one gap value, and give every tile a real piece of content. Empty decorative tiles look like a template.
  • Use subgrid (grid-template-rows: subgrid) when cards in a row need their titles, bodies and buttons to line up with each other.

7. Responsive structure

Design mobile first, then add structure as space grows.

  • Breakpoints follow content, not devices. Add one where the layout starts to look wrong. Tailwind's sm 640, md 768, lg 1024, xl 1280 are fine defaults.
  • Restructure, do not just shrink. On mobile, a three-column feature grid becomes one column, side-by-side text and image stack with the image second (or first if it carries the message), a table becomes a list of cards or scrolls horizontally inside its own container, a sidebar becomes a drawer.
  • Container queries for components that appear in different widths (a card in a sidebar and in a main column):
Source
.card-wrap { container-type: inline-size; }
@container (min-width: 480px) { .card { grid-template-columns: 160px 1fr; } }

In Tailwind v4: @container on the parent and @md:grid-cols-2 on the child.

  • Scale spacing with the screen. Section padding: 48px mobile, 64px tablet, 96px desktop. Gaps can step from 16 to 24 to 32.
  • Viewport height: use min-h-dvh (or 100dvh), not h-screen (100vh), for full-height layouts. 100vh is taller than the visible area on mobile browsers with a toolbar, so content hides under it.
  • Safe areas on phones with notches: padding-bottom: env(safe-area-inset-bottom) on fixed bottom bars, with viewport-fit=cover in the viewport meta tag.
  • Right-to-left languages: use logical properties (margin-inline-start, padding-inline, inset-inline-end; Tailwind ms-*, pe-*, start-*) instead of left and right, and test with dir="rtl". Mirror directional icons (back arrows, chevrons), not logos or every icon.
  • No horizontal page scroll, ever. Check at 320px. The usual causes are a fixed width, a long word or URL, a w-screen element (which includes the scrollbar width), or a negative margin.

8. Tables

  • Header row in the label role, sticky (position: sticky; top: 0) when the table scrolls, on a tinted surface or with a stronger bottom border.
  • Row height by density: 36px compact, 44px default, 52px comfortable. Offer a toggle when users differ.
  • Rows separated by hairline dividers or by zebra tint, not both.
  • Numbers end-aligned with tabular-nums; text start-aligned; status and actions in the last columns.
  • Wide tables on mobile: scroll horizontally inside their own container (overflow-x: auto) with the first column sticky, or switch to a stacked card per row. Never let a table push the page sideways.
  • Empty, loading and error states live inside the table frame, keeping the header so the user knows what will appear.

9. Density

Match density to how often the screen is used:

  • Marketing and onboarding: open. Few items per screen, generous space, large type.
  • Daily-use app screens: compact. Rows of 36 to 44px, 8 to 12px gaps, 14px text. People who use a screen every day want to see more at once.
  • Tables and data tools: dense, with a density toggle if users differ.
  • Do not mix densities within one panel.

10. Touch targets and hit areas

  • 44 by 44px target for anything tappable on touch screens, even if the visible icon is 16px. (WCAG 2.2 AA requires at least 24 by 24px; 44 is the comfortable size.) Grow the hit area with padding, or with an invisible pseudo-element centered on the control so the layout does not change:
Source
.icon-btn { position: relative; }
.icon-btn::before {
content: ""; position: absolute; left: 50%; top: 50%;
width: max(100%, 44px); height: max(100%, 44px);
transform: translate(-50%, -50%);
}
  • At least 8px between separate tap targets so a thumb does not hit two.

11. Layering

Keep a small z-index scale and use only these values:

Source
:root { --z-dropdown: 10; --z-sticky: 20; --z-overlay: 30; --z-modal: 40; --z-toast: 50; --z-tooltip: 60; }

Native <dialog> opened with showModal() and elements with the popover attribute render in the browser's top layer, above every z-index, so they need none. z-index: 9999 means the stacking is not understood. Fix the stacking context (often a stray transform, filter or isolation on a parent) instead of raising the number.

12. Sticky and fixed elements

  • Sticky headers: keep them short (56 to 64px), and give them a background (solid or blurred) only once the page scrolls under them, so the top of the page stays clean.
  • Add scroll-margin-top equal to the header height on anchored headings so in-page links do not land under the header.
  • Fixed bottom bars on mobile need the safe-area padding above and must not cover the last content on the page; pad the page bottom by the bar's height.

13. Check before you finish

  • Every spacing value is on the 4px scale.
  • Space inside groups is clearly smaller than space between them.
  • More space above headings than below.
  • One start edge per section; numbers end-aligned in tables.
  • Flexible tracks use minmax(0, 1fr); text children can shrink.
  • Paragraphs capped at about 65ch, even on wide screens.
  • Layout restructures on mobile instead of just shrinking.
  • No horizontal scroll at 320px; full-height sections use dvh.
  • Touch targets at least 44px (never under 24px).
  • z-index values come from the scale.
  • Squint test: the most important thing and the groups are clear with the details blurred.

Works well with

  • Typography

    Free

    Fonts, a role-based type scale, line height, tracking, measure, line breaks, numbers and font loading.

  • Dashboard and app UI

    Pro

    App shells, data tables, settings, dashboards, charts, detail panels, command menus and keyboard shortcuts.

  • Accessibility and UI states

    Pro

    Every interaction and data state, plus keyboard, touch, zoom, forced colors and screen readers.