better-layout
Improve interface structure through grouping, alignment, reading order, progressive disclosure, and adaptive responsive layouts.
Install
npx skills add https://github.com/jakubkrehel/skills --skill better-layoutSpacing and adaptivity
Recipes for control clearance, edge insets, disclosure cues, edge behavior, breakpoints and growth.
Borderless controls need more clearance
Nothing marks where one borderless target ends and the next begins, so the space is the boundary. Preserve an established, usable density rather than expanding controls to match these values.
Target sizes and hit-area expansion belong to better-accessibility. Space controls so their expanded hit areas never overlap.
Inset buttons from the edges
A button pressed against the viewport looks like system chrome and clips against curved corners and gesture zones.
The button can still span the full content width inside the margins.
Hint at hidden content
- Peeking items. A row of cards that ends exactly at the container edge looks complete, and nobody scrolls it.
- Disclosure controls. A collapsed section gets a chevron or a "Show more" control naming what is hidden: "Show 12 more results", not "More".
- Truncated values. Pair the clamp with an expand control, a link to a detail view or a tooltip that also opens on keyboard focus. A hover-only
titleattribute does not count, because keyboard and touch users never see it.
The item width sets the peek: width = 100% + gap − peek, since 100% is the container's content box. Scroll padding keeps snapped items on the content edge.
Content bleeds, controls float
Safe-area insets are physical, so a floating button pairs each physical side with its own inset and overrides it in RTL:
Hold structure until it breaks
Break where the layout stops fitting, not at 768px because a preset says so. That is where the sidebar squeezes content below its minimum measure, or a card grid drops below a usable column width.
A query styles only descendants of the container, never the container itself. container-type: inline-size adds size containment, so the container no longer takes its width from its content. A shrink-to-fit container such as a flex item with no width, an inline-block or an absolutely positioned box collapses to zero.
Plan for growth and clipping
A grid track or flex child refuses to shrink below its content's minimum width, so long words and wide tables push the layout past the viewport. Use grid-template-columns: minmax(0, 1fr) and min-width: 0 on flex children.
Fixed-height containers clip text at 200% zoom and in long locales. Use min-height where a floor is needed. Where a box must cap its height, pair max-height with overflow-y: auto.
Typical clip-prone spots are the bottom edge of a resizable pane, the bottom of a modal taller than the viewport and anything the on-screen keyboard covers:
- Size full-height panes with
100dvh, not100vh, which ignores mobile browser toolbars. - Give a modal
max-height: 100dvh, a scrolling body and an action row outside the scroll area. - Keep primary actions in stable chrome, such as a sticky footer with safe-area padding or the top of the view.