Grid Layout Rules
DryUI uses CSS grid for all layout — no flexbox, no layout components. These rules keep layout consistent, responsive, and easy to maintain across your entire application.
Core Principles
Five rules that govern all layout in DryUI.
-
Grid only
Every layout uses
display: grid. Never usedisplay: flexor DryUI layout components like Grid, Stack, or Flex. -
Container queries
Use
container-type: inline-sizewith@containerfor responsive behavior. Never use@mediafor sizing breakpoints. -
Spacing tokens
Always use
--dry-space-*tokens for gap and padding. Never hardcode pixel values for spacing. -
CSS custom properties
Expose layout configuration as
--varcustom properties so consumers can override values without touching your CSS. -
Scoped styles only
All layout CSS goes in scoped
<style>blocks. No inline styles, nostyle:directives, no:global(), no!important.
@media is for preferences only
The only valid use of @media queries is for user preference detection — never for sizing.
/* ✅ Correct — user preferences */
@media (prefers-reduced-motion: reduce) {
.animated { animation: none; }
}
@media (prefers-color-scheme: dark) {
/* theme adjustments */
}
/* ❌ Wrong — sizing breakpoints */
@media (min-width: 768px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
/* ✅ Correct — use @container instead */
.grid-wrapper { container-type: inline-size; }
@container (min-width: 768px) {
.grid { grid-template-columns: repeat(3, 1fr); }
} Responsive Card Grid
A grid that adapts its column count based on the container width using @container queries.
<div class="cards-wrapper">
<div class="cards">
<Card.Root>...</Card.Root>
<Card.Root>...</Card.Root>
<Card.Root>...</Card.Root>
</div>
</div>
<style>
.cards-wrapper {
container-type: inline-size;
}
.cards {
display: grid;
grid-template-columns: 1fr;
gap: var(--dry-space-4);
}
@container (min-width: 480px) {
.cards {
grid-template-columns: repeat(2, 1fr);
}
}
@container (min-width: 768px) {
.cards {
grid-template-columns: repeat(3, 1fr);
}
}
</style> Auto-fill Grid
When you don't need specific breakpoints, auto-fill with minmax lets the browser decide how many columns fit.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
gap: var(--dry-space-4);
} min() function prevents overflow on very narrow containers. Without it, items
would overflow when the container is smaller than 240px.Page Layout with Sidebar
Use named grid lines or template areas for page-level layout with sidebar, header, and footer.
.layout {
display: grid;
grid-template-columns: var(--sidebar-width, 260px) 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100dvh;
}
.header { grid-column: 1 / -1; }
.footer { grid-column: 1 / -1; } Centered Content with Full-bleed
A three-column grid trick that constrains content width while allowing full-bleed elements to break out.
.page {
display: grid;
grid-template-columns: 1fr min(var(--content-width, 72ch), 100%) 1fr;
}
.page > * {
grid-column: 2;
}
.page > .full-bleed {
grid-column: 1 / -1;
} Vertical Stacking
Replace flexbox column layouts with a single-column grid. Use --dry-space-* tokens for consistent vertical rhythm.
/* ❌ Don't use flexbox */
.stack {
display: flex;
flex-direction: column;
gap: 16px;
}
/* ✅ Use grid */
.stack {
display: grid;
gap: var(--dry-space-4);
} Spacing Scale
Use these tokens for all gap, padding, and margin values.
--dry-space-1 /* 4px */
--dry-space-2 /* 8px */
--dry-space-3 /* 12px */
--dry-space-4 /* 16px */
--dry-space-5 /* 20px */
--dry-space-6 /* 24px */
--dry-space-8 /* 32px */
--dry-space-10 /* 40px */
--dry-space-12 /* 48px */
--dry-space-16 /* 64px */ Lint Enforcement
These rules are enforced automatically by @dryui/lint — a Svelte preprocessor that runs during dev and build.