Zazz Design Framework
Foundations

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-xs for article (40rem / 640px) or --screen-lg for 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.

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.

Where to next

On this page