Skip to content

Layouts

Layout recipes provide consistent patterns for organizing content. They replace verbose utility classes with semantic, readable class names.

Vertical stacking layout for arranging items in a column.

ClassPurposeGap SizeExample
af-stackDefault vertical stackMedium (gap-md)<div class="af-stack">
af-stack-smSmall gap stackSmall (gap-sm)<div class="af-stack-sm">
af-stack-mdMedium gap stackMedium (gap-md)<div class="af-stack-md">
af-stack-lgLarge gap stackLarge (gap-lg)<div class="af-stack-lg">
af-stack-xlExtra large gap stackXL (gap-xl)<div class="af-stack-xl">
<div class="af-stack">
  <div class="af-card">
    Item 1
  </div>
  <div class="af-card">
    Item 2
  </div>
  <div class="af-card">
    Item 3
  </div>
</div>
<div class="af-stack-sm">
  Small spacing
</div>
<div class="af-stack">
  Default spacing (md)
</div>
<div class="af-stack-md">
  Medium spacing (same as default)
</div>
<div class="af-stack-lg">
  Large spacing
</div>

Basic stack (default gap-md):

Item 1

Item 2

Item 3

Stack sizes:

Small gap

Small gap

Default gap

Default gap

Large gap

Large gap

Horizontal layout with wrapping for arranging items in a row.

ClassPurposeGap SizeExample
af-inlineDefault horizontal wrapMedium (gap-md)<div class="af-inline">
af-inline-smSmall gap inlineSmall (gap-sm)<div class="af-inline-sm">
af-inline-mdMedium gap inlineMedium (gap-md)<div class="af-inline-md">
af-inline-lgLarge gap inlineLarge (gap-lg)<div class="af-inline-lg">
af-inline-xlExtra large gap inlineXL (gap-xl)<div class="af-inline-xl">
<div class="af-inline">
  <button class="af-btn">
    Button 1
  </button>
  <button class="af-btn">
    Button 2
  </button>
  <button class="af-btn">
    Button 3
  </button>
</div>
<div class="af-inline-sm">
  Small spacing
</div>
<div class="af-inline">
  Default spacing (md)
</div>
<div class="af-inline-lg">
  Large spacing
</div>
<div class="af-inline-xl">
  XL spacing
</div>
<div class="af-inline af-justify-start">
  Start aligned
</div>
<div class="af-inline af-justify-center">
  Center aligned
</div>
<div class="af-inline af-justify-end">
  End aligned
</div>
<div class="af-inline af-justify-between">
  Space between
</div>

Basic inline (default gap-md):

Inline sizes:

Justify content:

Layout primitives vs Display utilities: af-cluster, af-spread, and af-center are semantic layout recipes — each combines display, alignment, and gap in one class. They live in Layouts (this page). The Display & Alignment utilities (af-flex, af-justify-*, af-items-*) are low-level building blocks — use them when you need custom combinations (e.g. af-inline af-justify-end). Prefer layout recipes first; reach for utilities when you need fine-grained control.

RecipeEquivalent utilitiesUse when
af-clusteraf-inline af-items-center af-gap-mdTags, chips, grouped buttons
af-spreadaf-inline af-items-center af-justify-betweenHeader left/right, space-between
af-centeraf-flex af-justify-center af-items-center or display: grid; place-items: centerCentering content on both axes

Cluster and spread are lightweight inline layout recipes for common alignment patterns. Default to these semantic recipes, and use explicit alignment utilities when you need fine-grained control.

ClassPurposeExample
af-clusterInline cluster (wrap + center alignment)<div class="af-cluster">
af-spreadInline spread (space-between)<div class="af-spread">
<div class="af-cluster">
  <span class="af-chip">
    Tag 1
  </span>
  <span class="af-chip">
    Tag 2
  </span>
  <span class="af-chip">
    Tag 3
  </span>
</div>
<div class="af-spread">
  <span>
    Left
  </span>
  <span>
    Right
  </span>
</div>

Explicit equivalents (when needed):

<div class="af-inline af-items-center af-gap-md">
  <span>
    Cluster content
  </span>
  <span>
    Cluster content
  </span>
</div>
<div class="af-inline af-items-center af-justify-between">
  <span>
    Left
  </span>
  <span>
    Right
  </span>
</div>

Cover - Full-viewport hero layout (min-height: 100dvh, centered content):

<section class="af-cover af-bg-primary">
  <div class="af-stack af-gap-lg af-center">
    <h1 class="af-text-fluid-h1 af-text-on-primary">
      Hero
    </h1>
    <p class="af-text-on-primary-muted">
      Centered full-viewport layout
    </p>
  </div>
</section>

Sidebar - Main content + sidebar (stacks on mobile, side-by-side on tablet+):

<div class="af-sidebar">
  <main>
    Main content (1fr)
  </main>
  <aside class="af-card">
    Sidebar (min 250px)
  </aside>
</div>

Centers content horizontally and vertically.

<div class="af-center" style="min-height: 200px;">
  <div class="af-card">
    <p class="af-card__body">
      Centered
    </p>
  </div>
</div>

Explicit equivalent:

<div class="af-inline af-justify-center af-items-center" style="min-height: 200px;">
  <div class="af-card">
    <p class="af-card__body">
      Centered
    </p>
  </div>
</div>

Centered content wrapper with max-width and horizontal padding. Use one class per element.

ClassMax WidthUse Case
af-container90em (1440px)Default, standard page content
af-container-xs25rem (400px)Narrow forms, sidebars
af-container-sm40rem (640px)Narrow content
af-container-md48rem (768px)Tablet-optimized
af-container-lg64rem (1024px)Desktop content
af-container-xl80rem (1280px)Wide layouts
af-container-2xl96rem (1536px)Extra-wide layouts

For responsive sizing, use the responsive suffix: af-container af-container-lg@xl (default on mobile, large at xl breakpoint).

<div class="af-container">
  <!-- Content with max-width and centering -->
</div>
<div class="af-container-xs">
  Extra small (400px max)
</div>
<div class="af-container-sm">
  Small (640px max)
</div>
<div class="af-container-md">
  Medium (768px max)
</div>
<div class="af-container-lg">
  Large (1024px max)
</div>
<div class="af-container-xl">
  Extra large (1280px max)
</div>

Default container:

Container content with default max-width (90em / 1440px)

Container sizes:

xs - 400px max

sm - 640px max

md - 768px max

lg - 1024px max

xl - 1280px max

Surface pattern for creating simple containers with background, border, and border-radius. Unlike cards, surfaces don’t include padding or shadows—you add those yourself.

<div class="af-surface af-p-md">
  <p>
    Surface with padding added
  </p>
</div>

Use af-is-* modifier classes to change the surface background:

<div class="af-surface">
  Default surface (primary)
</div>
<div class="af-surface af-is-secondary">
  Secondary surface
</div>
<div class="af-surface af-is-tertiary">
  Tertiary surface
</div>
  • Surface (af-surface): Simple container without padding or shadow. Use for panels, backgrounds, or when you need full control over spacing.
  • Card (af-card): Full component with padding, shadow, and semantic parts. Use for content containers with structure.

Default surface (primary background)

Secondary surface variant

Tertiary surface variant

Section pattern for consistent vertical spacing between page sections. Adds padding-block (top and bottom padding) to create visual separation.

<section class="af-section">
  <h2>
    Section Title
  </h2>
  <p>
    Section content
  </p>
</section>
<section class="af-section-sm">
  Small spacing
</section>
<section class="af-section">
  Default spacing
</section>
<section class="af-section-lg">
  Large spacing
</section>
<section class="af-section-hero">
  Hero (extra padding)
</section>
<section class="af-section-alt">
  Alternate background
</section>
<section class="af-section-narrow">
  Narrow container
</section>
  • af-section-hero - Extra padding for hero sections
  • af-section-alt - Alternate background (--af-color-surface-primary)
  • af-section-narrow - Constrains child .af-container to --af-container-max-w-md
  • Page sections with consistent spacing
  • Content areas that need vertical rhythm
  • Separating major content blocks

Small Section

Reduced vertical spacing (space-4)

Default Section

Standard vertical spacing (space-6)

Large Section

Increased vertical spacing (space-8)

Utility for adding vertical spacing (margin-block) between elements. Useful when you need spacing but don’t want to use a full stack layout.

<div>
  Content
</div>
<div class="af-spacer-sm">
  Small spacer above
</div>
<div>
  Content
</div>
<div class="af-spacer-md">
  Medium spacer above
</div>
<div>
  Content
</div>
<div class="af-spacer-lg">
  Large spacer above
</div>
  • af-spacer-sm - Small spacing (space-2)
  • af-spacer-md - Medium spacing (space-4)
  • af-spacer-lg - Large spacing (space-6)
  • Adding spacing between individual elements
  • Creating gaps in non-stack layouts
  • Quick vertical rhythm without changing layout structure

Note: For consistent vertical layouts, prefer af-stack with gap utilities. Use spacer for one-off spacing needs.

Content

Small spacer above

Content

Medium spacer above

Content

Large spacer above

Content

Position utilities for controlling element positioning and placement.

<div class="af-pos-relative">
  Relative positioning
</div>
<div class="af-pos-absolute">
  Absolute positioning
</div>
<div class="af-pos-sticky">
  Sticky positioning
</div>
<div class="af-pos-revert">
  Revert to default
</div>
<div class="af-relative">
  Relative (shorthand)
</div>
<div class="af-absolute">
  Absolute (shorthand)
</div>
<div class="af-sticky">
  Sticky (shorthand)
</div>
<div class="af-absolute af-top-0 af-left-0">
  Top-left corner
</div>
<div class="af-absolute af-top-0 af-right-0">
  Top-right corner
</div>
<div class="af-absolute af-bottom-0 af-left-0">
  Bottom-left corner
</div>
<div class="af-absolute af-bottom-0 af-right-0">
  Bottom-right corner
</div>

Position:

  • af-pos-relative / af-relative - position: relative
  • af-pos-absolute / af-absolute - position: absolute
  • af-pos-sticky / af-sticky - position: sticky
  • af-pos-revert - position: revert

Offsets:

  • af-inset-0 - inset: 0 (all edges)
  • af-top-0 - top: 0
  • af-right-0 - right: 0
  • af-bottom-0 - bottom: 0
  • af-left-0 - left: 0

Top-left

Top-right

Bottom-left

Bottom-right

Relative container

All layout classes support responsive variants using the @{bp} suffix. See Responsive Suffix for the full syntax and breakpoint table.

<div class="af-stack af-stack-lg@md">
  <!-- Medium gap on mobile, large gap on tablet+ -->
</div>
<div class="af-container af-container-lg@xl">
  <!-- Default container on mobile, large container on desktop -->
</div>

Control alignment in flex containers:

<div class="af-inline af-justify-start">
  Start
</div>
<div class="af-inline af-justify-center">
  Center
</div>
<div class="af-inline af-justify-end">
  End
</div>
<div class="af-inline af-justify-between">
  Space Between
</div>
<div class="af-inline af-justify-around">
  Space Around
</div>
<div class="af-inline af-justify-evenly">
  Space Evenly
</div>
<div class="af-inline af-items-start">
  Start
</div>
<div class="af-inline af-items-center">
  Center
</div>
<div class="af-inline af-items-end">
  End
</div>
<div class="af-inline af-items-stretch">
  Stretch
</div>
<div class="af-inline af-items-baseline">
  Baseline
</div>
<div class="af-inline af-justify-start af-justify-center@md">
  Start on mobile, center on tablet+
</div>

Justify content examples:

Align items examples:

Masonry layout creates a waterfall-style layout where items flow into columns based on their height, similar to Pinterest-style layouts.

⚠️ Experimental Feature - Uses CSS Grid Lanes, which has very limited browser support. See Browser Support for details.

  • Safari Technology Preview 234+ (December 2025) - Full support
  • ⚠️ Chrome 140+ - Available behind experimental flag
  • ⚠️ Firefox 147+ - Available behind experimental flag
  • ⚠️ Edge - Available behind experimental flag

Fallback: In unsupported browsers, automatically falls back to regular CSS Grid (items display in a standard grid, not masonry).

ClassPurposeColumn WidthExample
af-masonryDefault masonry250px minimum<div class="af-masonry">
af-masonry-smSmall columns200px minimum<div class="af-masonry-sm">
af-masonry-mdMedium columns250px minimum<div class="af-masonry-md">
af-masonry-lgLarge columns300px minimum<div class="af-masonry-lg">
af-masonry-xlExtra large columns400px minimum<div class="af-masonry-xl">
af-masonry-textText-optimized20ch minimum<div class="af-masonry-text">
<div class="af-masonry af-gap-lg">
  <div class="af-card">
    Item 1
  </div>
  <div class="af-card">
    Item 2
  </div>
  <div class="af-card">
    Item 3
  </div>
  <div class="af-card">
    Item 4
  </div>
</div>
<div class="af-masonry-sm">
  Small columns (200px min)
</div>
<div class="af-masonry">
  Default columns (250px min)
</div>
<div class="af-masonry-lg">
  Large columns (300px min)
</div>
<div class="af-masonry-xl">
  Extra large columns (400px min)
</div>
<div class="af-masonry-text">
  Text-optimized (20ch min)
</div>

Card 1

Short content

Card 2

This card has more content to demonstrate how masonry layouts work. Items flow into columns based on their height.

Card 3

Medium content here

Card 4

Another short card

Card 5

This is a longer card with more content to show how items of different heights flow into the masonry layout. The browser automatically places each item in the column that gets it closest to the top.

Card 6

Short

  • Photo galleries with varying image heights
  • Card layouts with different content lengths
  • Article teasers or blog post previews
  • Product listings with varying descriptions

For production use in unsupported browsers, consider using a JavaScript polyfill:

// Feature detect and load polyfill if needed
if (!CSS.supports('display', 'grid-lanes')) {
import('masonry-layout').then(({ default: Masonry }) => {
  const grids = document.querySelectorAll('.af-masonry');
  grids.forEach(grid => {
    new Masonry(grid, {
      itemSelector: '> *',
      columnWidth: 250,
      gutter: 16
    });
  });
});
}

See Browser Support for more details.

Control spacing between grid items or flex items:

Source of truth: Gap utilities are defined in grid.css and documented in Grid.

ClassGap SizeToken ValueExample
af-gap-0No gap--af-space-0<div class="af-grid af-grid-2 af-gap-0">
af-gap-xsExtra small--af-space-1<div class="af-grid af-grid-2 af-gap-xs">
af-gap-smSmall--af-space-2<div class="af-grid af-grid-2 af-gap-sm">
af-gap-lgLarge--af-space-4<div class="af-grid af-grid-2 af-gap-lg">
af-gap-xlExtra large--af-space-5<div class="af-grid af-grid-2 af-gap-xl">
af-gap-2xl2XL--af-space-6<div class="af-grid af-grid-2 af-gap-2xl">
af-gap-3xl3XL--af-space-7<div class="af-grid af-grid-2 af-gap-3xl">
af-gap-4xl4XL--af-space-8<div class="af-grid af-grid-2 af-gap-4xl">
(default)Medium (default)--af-space-3<div class="af-grid af-grid-2">

Usage: Gap utilities can override default gaps in any layout recipe:

<div class="af-stack af-gap-lg">
  Override stack's default gap
</div>
<div class="af-inline af-gap-sm">
  Override inline's default gap
</div>
<div class="af-grid af-grid-2 af-gap-xl">
  Override grid's default gap
</div>

All classes available in layouts.css:

  • af-stack - Default vertical stack (medium gap)
  • af-stack-sm - Small gap vertical stack
  • af-stack-md - Medium gap vertical stack (same as default)
  • af-stack-lg - Large gap vertical stack
  • af-stack-xl - Extra large gap vertical stack
  • af-inline - Default horizontal wrap (medium gap)
  • af-inline-sm - Small gap horizontal wrap
  • af-inline-md - Medium gap horizontal wrap (same as default)
  • af-inline-lg - Large gap horizontal wrap
  • af-inline-xl - Extra large gap horizontal wrap
  • af-cluster - Inline cluster (wrap + center alignment)
  • af-spread - Inline spread (space-between)
  • af-center - Center contents on both axes
  • af-container - Default container (90em / 1440px max-width)
  • af-container-xs - Extra small container (400px max-width)
  • af-container-sm - Small container (640px max-width)
  • af-container-md - Medium container (768px max-width)
  • af-container-lg - Large container (1024px max-width)
  • af-container-xl - Extra large container (1280px max-width)
  • af-container-2xl - 2xl container (1536px max-width)
  • af-gap-0 - No gap
  • af-gap-xs - Extra small gap
  • af-gap-sm - Small gap
  • af-gap-md - Medium gap
  • af-gap-lg - Large gap
  • af-gap-xl - Extra large gap
  • af-gap-2xl / af-gap-3xl / af-gap-4xl - Larger gaps (--af-space-68)

Total: 29 layout classes - All support responsive variants with @ suffix (e.g., af-stack@md)

Note: Grid classes are documented separately. See Grid for complete grid documentation.

  • Use af-stack for vertical layouts
  • Use af-inline for horizontal wrapping layouts
  • See Grid for grid layouts (equal columns and 12-column system)
  • Prefer layout recipes (af-stack, af-inline, af-grid, af-container) over many atomic utility classes
  • Use responsive suffixes for breakpoint-specific styles
  • Combine layout recipes with pattern classes for complex layouts
  • Use af-justify-* and af-items-* for fine-grained alignment control
  • Grid — equal columns and the 12-column system
  • Responsive Suffix — breakpoint variants with @
  • Recipes — copy-paste page compositions built from these primitives