Layout
Two self-padding semantic widths and a breakpoint scale for calcs.
Two layout widths replace the wrapping .container div.
Zazz ships two semantic widths: --article for reading-focused content and --container for full-width page sections. Both wrap their max-width in a min() that falls back to side-padding when the viewport is narrower than the cap. Apply the variable directly to your element. No wrapping div, no media-query plumbing.
.section-inner {
width: var(--container);
margin-inline: auto;
}
.article-body {
width: var(--article);
margin-inline: auto;
}Semantic widths
--article: min(var(--screen-xs), 100% - var(--gap-md) * 2);
--container: min(var(--screen-lg), 100% - var(--gap-md) * 2);What the math is doing:
- On wide viewports (wider than the max) the element resolves to
--screen-xsfor article (40rem / 640px) or--screen-lgfor container (80rem / 1280px). Capped. - On narrow viewports (narrower than the max) the element resolves to
100% minus 2 × --gap-md. The 24px gutter on each side is built in.
One variable does what most setups need a .container div, a @media rule, and a padding override to accomplish.
--article exists for long-form reading where line length matters. 40rem (640px) is roughly 65–75 characters at default body size, a comfortable range for sustained reading. --container is for everything else: page sections, hero blocks, grid layouts.
Yes. Define your own with the same min() pattern:
:root {
--container-narrow: min(var(--screen-md), 100% - var(--gap-md) * 2);
--container-wide: min(var(--screen-xl), 100% - var(--gap-md) * 2);
}Use them like --container. A marketing site with both a typical content width and a wider hero width benefits from a third.
If you're defining three or four containers, the design may want fewer breakpoints rather than more containers. Most layouts compose better from two well-chosen widths than four similar ones.
Breakpoints
--screen-xs: 40rem; /* 640px */
--screen-sm: 48rem; /* 768px */
--screen-md: 64rem; /* 1024px */
--screen-lg: 80rem; /* 1280px */
--screen-xl: 96rem; /* 1536px */The breakpoint tokens are named constants for layout sizing. Use them in calc() and any computed layout value:
.full-bleed {
width: 100%;
max-width: var(--screen-xl);
}
.split {
/* fill the gap between the article column and the screen edge */
width: calc((100vw - var(--article)) / 2);
}
.feature-card {
width: calc(var(--screen-md) / 3);
}The breakpoint tokens are also the natural source values for @media queries. The CSS spec doesn't allow custom properties inside media query conditions, so you'll hardcode the raw 40rem, 48rem, etc. in the query and use the variable everywhere else that needs the same number.
@media (min-width: 48rem) {
/* matches --screen-sm */
.nav {
flex-direction: row;
}
}The same restriction applies to container queries with size conditions (@container (min-width: ...)). Variables work inside style queries (@container style(...)) but not size queries.