Layout
A few composable layout primitives instead of a utility matrix - helpers/layout.css. Live/interactive (drag to resize the container): Layout demo.
Container
| Class | Purpose |
|---|---|
.ncss-container | Centered, width-limited column with side padding. Also establishes the named container ncss-container - the basis for every container-query class on this page |
.ncss-container--narrow | Modifier, ONLY together with .ncss-container - narrower max-width |
.ncss-full-bleed | Breaks out of a container to the edge of the screen |
Grid: intrinsic (the default path)
.ncss-grid - automatically responsive grid with no media queries (repeat(auto-fit, minmax(...))), minimum column width parametrized via a custom property. Equal row height happens automatically (a CSS Grid default):
<div class="ncss-grid" style="--ncss-grid-min: 16rem;">
<div>Card 1</div>
<div>Card 2</div>
</div>
--ncss-grid-max additionally caps column growth (default 1fr, unbounded) - against absurdly wide columns when there are few items on a very wide screen. .ncss-grid--align-start disables row stretching, if cards of different heights should NOT be stretched to match.
Grid: fixed column count (escape hatch)
For a genuinely FIXED, editorially chosen column count instead of .ncss-grid's automatic count - .ncss-grid--cols-2/-3/-4/-6, collapses to 1 column below the respective threshold. Needs an ancestor with .ncss-container (or another element carrying container-name: ncss-container):
<div class="ncss-container">
<div class="ncss-grid--cols-3">
<div>1</div><div>2</div><div>3</div>
</div>
</div>
| Class | Threshold (container width) |
|---|---|
.ncss-grid--cols-2 | 24rem |
.ncss-grid--cols-3 | 36rem |
.ncss-grid--cols-4 | 48rem |
.ncss-grid--cols-6 | 56rem |
Unequal tile widths: combine children with .ncss-col-span-2/-3/.ncss-row-span-2/-3 as well (also usable with .ncss-bento below). Mixed tile sizes with no fixed grid at all: .ncss-bento (grid-auto-flow: dense, fills gaps automatically). Column-based fallback masonry with progressive enhancement to true row-accurate display: grid-lanes once available: .ncss-masonry.
Flex helpers
| Class | Purpose |
|---|---|
.ncss-flex | display: flex + a default gap |
.ncss-flex--wrap | Allow wrapping |
.ncss-flex--center | Centered on both axes |
.ncss-flex--between | space-between, vertically centered |
.ncss-flex--column | Vertical instead of horizontal direction |
.ncss-flex-1 (child) | Grows/shrinks, shares the available space (flex: 1 1 0%) |
.ncss-flex-auto (child) | Stays at its own content width (flex: 0 0 auto) |
.ncss-stack/.ncss-cluster (see above) are already calibrated flex patterns for the two most common cases (vertical rhythm/horizontally flowing group) - .ncss-flex is for everything else.
Flex grid with width fractions
For the one case .ncss-grid does NOT cover: a FIXED column count where an incomplete last row should be CENTERED instead of hanging left-aligned (e.g. 5 cards - 3 in row 1, 2 in row 2, centered rather than stuck to the edge). CSS Grid can't do this (every column stays part of the fixed track structure) - a wrapping flex container with explicit child widths can, because each row flows independently:
<div class="ncss-flex-grid ncss-flex-grid--center">
<div class="ncss-width-1-3">1</div>
<div class="ncss-width-1-3">2</div>
<div class="ncss-width-1-3">3</div>
<div class="ncss-width-1-3">4</div>
<div class="ncss-width-1-3">5</div>
</div>
.ncss-flex-grid establishes its OWN named container (ncss-flex-grid) - independent of whether an ancestor is already .ncss-container. Each width class reacts to the width of .ncss-flex-grid ITSELF via @container: ONE class name per fraction, no "class × breakpoint" matrix like UIkit/Tailwind-style systems typically use - always starts at 100% (stacked) until the fraction's own threshold is reached (the same four values as .ncss-grid--cols-* above, plus two more for fifths/sixths):
| Class | Fraction | Threshold |
|---|---|---|
.ncss-width-1-2 | 1/2 | 24rem |
.ncss-width-1-3 / .ncss-width-2-3 | 1/3 / 2/3 | 36rem |
.ncss-width-1-4 / .ncss-width-3-4 | 1/4 / 3/4 | 48rem |
.ncss-width-1-5 | 1/5 (intermediate: 1/2 from 48rem) | 52rem |
.ncss-width-1-6 | 1/6 | 56rem |
.ncss-flex-grid--center centers an incomplete last row (justify-content: center) - the actual reason this building block exists. Internally compensated via calc() for the gap share (a plain percentage width would wrap too early in a wrapping flex container with gap, since gap is NOT automatically subtracted from a percentage basis, unlike CSS Grid's fr units - confirmed via a real test). Combinable with .ncss-card: any .ncss-width-* element can itself be a card or wrap one.
Container-based visibility
Like .ncss-hide-below-md/-from-md (a fixed viewport breakpoint, helpers/visibility.css - see Scroll & Visibility), but reacts to the width of the parent .ncss-container, not the viewport - the same component shows/hides an element depending on its own column width (e.g. a sidebar vs. main-column variant), independent of screen size:
<div class="ncss-container">
<p class="ncss-hide-below-container-md">Only visible from 36rem container width</p>
<p class="ncss-hide-from-container-md">Only visible below 36rem container width</p>
</div>
Four thresholds, the same ones used throughout this page: -sm (24rem), -md (36rem), -lg (48rem), -xl (56rem). For any OTHER property (not just visibility) at a given container width - use the same @container ncss-container (min-width: ...) technique directly in your own CSS, see Build Your Own Components.
Stack & Cluster
| Class | Purpose |
|---|---|
.ncss-stack | Vertical flex stack with even spacing |
.ncss-stack--tight / --loose | Tighter/looser spacing than the default |
.ncss-cluster | Horizontal group, wraps automatically (e.g. tag lists, button groups) |
Bleed
Variants for deliberately breaking out of a container: .ncss-bleed-start/-end (one side), .ncss-bleed-half-start/-half-end (from the middle), .ncss-bleed-center (symmetric by a fixed amount, --ncss-bleed-amount).
See also
For whole landing-page pieces (not just individual building blocks): Landing Page Blocks - text & image (Split), color-block sections (Tile), transforming accordion (Accordion-Split). For cards themselves (header/body/footer/media, horizontal/flush): Cards. All container-query-responsive, combinable with .ncss-container/.ncss-full-bleed from above.