Basic Grid
The .nds-grid class creates a CSS grid that distributes children into equal columns. Use --max-col to set a fixed column count, or --min-width to set a minimum column width for automatic wrapping.
<div class="nds-grid" style="--max-col: 3;">
<div class="nds-card nds-stroke">1</div>
<div class="nds-card nds-stroke">2</div>
<div class="nds-card nds-stroke">3</div>
<div class="nds-card nds-stroke">4</div>
<div class="nds-card nds-stroke">5</div>
<div class="nds-card nds-stroke">6</div>
</div>
<div class="nds-grid" style="--min-width: 200px;">
<div class="nds-card nds-stroke">1</div>
<div class="nds-card nds-stroke">2</div>
<div class="nds-card nds-stroke">3</div>
<div class="nds-card nds-stroke">4</div>
<div class="nds-card nds-stroke">5</div>
<div class="nds-card nds-stroke">6</div>
</div>
Custom Track Layouts
Use --max-track to define an explicit grid-template-columns value for asymmetric layouts like a sidebar next to a main column, or a mix of fixed and flexible tracks.
<div class="nds-grid" style="--max-track: 3fr 1fr; --mid-track: 2fr 1fr; --min-track: 1fr;">
<div class="nds-card nds-stroke">Primary</div>
<div class="nds-card nds-stroke">Secondary</div>
</div>
<!-- Auto-fit at large, forced single column at medium and below -->
<div class="nds-grid" style="--mid-track: 1fr;">
<div class="nds-card nds-stroke">A</div>
<div class="nds-card nds-stroke">B</div>
<div class="nds-card nds-stroke">C</div>
</div>
Responsive Auto-fit
Use --max-col, --mid-col, and --min-col to set column count per viewport. Each token cascades: --mid-col falls back to --max-col, and --min-col falls back to --mid-col then --max-col.
<div class="nds-grid" style="--max-col: 4; --mid-col: 2; --min-col: 1;">
<div class="nds-card nds-stroke">A</div>
<div class="nds-card nds-stroke">B</div>
<div class="nds-card nds-stroke">C</div>
<div class="nds-card nds-stroke">D</div>
</div>
Responsive Breakpoints
The grid switches between --max-*, --mid-*, and --min-* tokens based on two triggers: the viewport width (standard media queries) and, when placed inside a section wrapper or block, the nearest container's width (CSS container queries). Whichever trigger crosses first collapses to the narrower token. Gap values halve at the mid breakpoint.
| Active Token | Viewport (media query) | Container (nearest section/block) | Fallback Chain |
|---|---|---|---|
| --max-col / --max-track | 961px+ | > 768px | auto-fit |
| --mid-col / --mid-track | 601px to 960px | ≤ 768px | --max-col → auto-fit |
| --min-col / --min-track | ≤ 600px | ≤ 480px | --mid-col → --max-col → auto-fit |
Customization Tokens
Override these CSS custom properties on .nds-grid to customize column count, track template, gap, and alignment.
<!-- Custom gap and fixed column count -->
<div class="nds-grid" style="--max-col: 3; --gap: var(--spacing-md); --row-gap: var(--spacing-xl);">
<div>...</div>
<div>...</div>
<div>...</div>
</div>
<!-- Minimum column width (auto-wraps when items can't fit at 250px) -->
<div class="nds-grid" style="--min-width: 250px;">
<div>...</div>
<div>...</div>
<div>...</div>
</div>
<!-- Responsive: 4 cols large, 2 cols medium, 1 col small -->
<div class="nds-grid" style="--max-col: 4; --mid-col: 2; --min-col: 1;">
<div>...</div>
<div>...</div>
</div>
<!-- Explicit track template with responsive collapse -->
<div class="nds-grid" style="--max-track: 3fr 1fr; --min-track: 1fr;">
<div>Primary</div>
<div>Secondary</div>
</div>
<!-- Centered grid items -->
<div class="nds-grid nds-center">
<div>...</div>
</div>
Built-in Features
Grid children distribute into equal columns automatically, filling available width without manual column counts.
Set --min-width to wrap items naturally once they cannot fit the specified minimum, no media queries needed.
Set different column counts with --max-col, --mid-col, and --min-col, triggered by viewport or the nearest container width, each cascading to the next as a fallback.
Define explicit grid-template-columns per breakpoint with --max-track, --mid-track, and --min-track for asymmetric layouts.
Gap and row-gap values halve automatically at the mid breakpoint (tablet viewport or a 768px-wide container), keeping spacing proportional in narrower contexts.
Control horizontal and vertical alignment of grid items through --justify and --align custom properties.
When placed inside a section wrapper or block, the grid responds to the nearest container's width via CSS container queries — correct column counts in sidebar layouts without viewport-only media queries.
Usage Guidelines
Best Practices
- Use auto-fit mode (no column tokens) for uniform card grids, gallery layouts, and collections where items should wrap naturally into equal columns
- Use responsive column tokens (
--max-col,--mid-col,--min-col) when you want specific column counts per breakpoint rather than fluid wrapping - Use track tokens (
--max-track,--mid-track,--min-track) for asymmetric layouts like sidebar + main content where columns need different widths - Set
--mid-track: 1fror--min-track: 1fralone (without--max-track) to keep auto-fit behavior at large viewports while forcing a single-column stack below - Prefer
--min-widthover--max-colwhen the ideal column count depends on available space rather than a fixed number - Do not use the grid for single-column page flow. Standard block layout handles this without extra markup
- Do not nest
.nds-gridinside.nds-gridfor complex page structures. Use Section to organize content into visual blocks - Always set
--min-color--min-track(commonly to1or1fr) when using responsive tokens, so layouts collapse cleanly on narrow viewports - Override
--gapwith a spacing token when the defaultvar(--spacing-2xl)is too wide for compact layouts like form fields or icon grids
Modifier Classes
| Class | Description |
|---|---|
nds-center | Centers grid items horizontally (sets --justify: center) |
CSS Custom Properties
| Property | Default | Description |
|---|---|---|
--max-col | auto-fit | Column count at large viewport (961px+). Base value for the fallback chain |
--mid-col | var(--max-col) | Column count at medium viewport (601px to 960px) |
--min-col | var(--mid-col) | Column count below 601px |
--max-track | (unset) | Explicit grid-template-columns value at large viewport. Overrides --max-col |
--mid-track | var(--max-track) | Track template at medium viewport |
--min-track | var(--mid-track) | Track template below 601px |
--min-width | 0 | Minimum column width inside minmax() for auto-fit wrapping (e.g. 250px) |
--gap | var(--spacing-2xl) | Shorthand for both row and column gap. Halved automatically below the large breakpoint |
--row-gap | var(--spacing-2xl) | Row gap override |
--col-gap | var(--spacing-2xl) | Column gap override |
--justify | stretch | Horizontal alignment of grid items (justify-items) |
--align | start | Vertical alignment of grid items (align-items) |