Layout patterns

This section covers our primary patterns for differentiating and organizing content based on user needs. The organizing principle to follow throughout: Choose typographic and proximity-based organization patterns first, reach for visible containers only when called for.

Evaluating user needs

What a user needs to learn determines the right organizational pattern to employ for any group of content. Use the four questions below as a starting point. Each question has a test and a set of patterns that answer it. Most content will fit under one of these questions. Have an edge case? Discuss it with the design team.

Where am I?

The address or the item changes.

What matters here?

Directing user attention.

Which part do I need?

The content swaps in place.

Can I learn more?

Richer details are revealed upon request.

The main content comes first

Before choosing components, decide what the page is for and which content is primary. Everything else is arranged so it does not push the primary content down.

Where secondary content goes

Each kind of secondary content has a home that keeps the main content high and wide. Compare at least two homes for each piece, and keep the one that leaves the main content highest and widest.

The page container

Every page sits in .ds-container. It centres the content in a column at the standard reading width, 850px at most, with a margin of at least 24px on each side. For a band that runs edge to edge, see Page zones.

<main class="ds-container">…</main>

.ds-container places every direct child in the reading column and puts --ds-space-section (48px) between them, so a section has no margin of its own.

A sidebar sits to the right of the main column and contains supplementary content. If the content is secondary, distinct from the main content, and it is important that it not be pushed far down the page, then a sidebar is appropriate.

The sidebar has no background and no border. Space alone separates it from the reading column and separates its blocks from each other.

Heavy-tailed gradients in deep networks

We study the convergence of stochastic gradient methods when the gradient noise is heavy-tailed, and show that the step size must shrink with the tail index.

Relevant code
<div>
<article>…</article>
<aside class="ds-sidebar" aria-label="Paper details">
  <details class="ds-acc" open>
    <summary>Versions</summary>
    <div class="ds-acc-body">
      <dl>
        <dt>v3 · current</dt><dd>24 Apr 2026</dd>
        <dt>v2</dt><dd><a href="#">2 Mar 2026</a></dd>
      </dl>
    </div>
  </details>
  <details class="ds-acc">
    <summary>Paper information</summary>
    <div class="ds-acc-body">…</div>
  </details>
</aside>
</div>
.ds-sidebar
On an <aside> with an aria-label that names what it holds: a complementary landmark. Its parent becomes the two-column layout, with the main content taking the spare width, the sidebar 17rem wide, and --ds-space-section between them. Blocks inside the sidebar are 24px apart (--ds-space-6). Nothing in it is sticky.
<aside>
The sidebar comes after the main content in the markup. When the two no longer fit side by side, the sidebar wraps below the content at full width, and a screen reader meets the article first.
.ds-acc
An accordion inside the sidebar drops its rules, goes single-column for the narrow measure, and turns its +/− marker Link Blue so a closed one still reads as interactive. No extra class.

Dividers

A rule between things. It belongs in the same conversation as the card, because both answer the same question and the answer is usually neither: this system groups with space first, and a line drawn where space would have done adds noise without adding meaning.

Standard gap

A section of content.


The next section.


And the one after it.

Relevant code
<p>A section of content.</p>
<hr>
<p>The next section.</p>
<hr>
<p>And the one after it.</p>
<hr>
The preferred form. Styled by the foundation with 32px above and below (--ds-space-8), no class needed, and it includes role="separator" for free.

Tight gap

An item in a group.


The next item in the same group.


And the one after it.

Relevant code
<p>An item in a group.</p>
<hr class="ds-divider ds-divider--tight">
<p>The next item in the same group.</p>
<hr class="ds-divider ds-divider--tight">
<p>And the one after it.</p>
.ds-divider--tight
Between items in a group rather than between sections: 16px above and below (--ds-space-block). It works on an <hr>, which keeps the separator meaning.
.ds-divider--flush
No margin at all; the caller owns the spacing.

Vertical dividers in a row of controls

Search Submit Donate
Relevant code
<div class="ds-btn-group">
<span>Search</span>
<span class="ds-divider ds-divider--vertical" aria-hidden="true"></span>
<span>Submit</span>
<span class="ds-divider ds-divider--vertical" aria-hidden="true"></span>
<span>Donate</span>
</div>
.ds-divider
The class form, for where an <hr> will not fit: inside a flex row, or on an element that is already there. It is decorative, so mark it aria-hidden — a real separator should be an <hr>.
.ds-divider--vertical
For a row of controls. Height is in em, so it follows the row's own text instead of needing a value per context.

Marginalia and gutter space

At wide screen widths, our max content width leaves enough gutter space on the sides for marginalia. A short note beside the block it belongs to is appropriate for annotation-style content. At narrower widths, it is hidden in an info icon in the block’s top-right corner. Try it by widening and narrowing your screen.

Note

A margin note is one or two sentences. Anything longer belongs in the main content.

The block the note belongs to: a paragraph, a figure, a table or a card. Any block works once it is positioned (position: relative); a card already is.

Relevant code
<div class="ds-card">
<details class="ds-marginalia">
  <summary><svg aria-hidden="true">…</svg><span class="is-sr-only">Note</span></summary>
  <p class="ds-marginalia-body ds-annotation">The note.</p>
</details>
…
</div>
.ds-marginalia
The note, a <details>. Its first child in the block, so it is read before the thing it annotates. The block supplies position: relative; .ds-card already does.
.ds-marginalia-body
The text, with .ds-annotation for the voice. In the margin it has no chrome; folded, it opens as a small panel under the mark.
.is-sr-only
Required on the mark. The icon is aria-hidden, so without it the control announces as nothing.

Accessibility essentials

Modifiers

Page zones

The default page background is white, and that is the color that primary page content sits on. The secondary zone is a tinted band for what introduces or supports that content: the opening of the page, and any closing material. The zone is named for its role, because the ground changes in dark mode.

A zone is optional. Without one, the whole page is on the page ground, --ds-canvas (white in light mode).

The secondary zone is a full band: a direct child of the container marked .ds-full, which runs edge to edge while its own content lines up with the reading column. Note that .ds-full adds no background colour. A band is coloured only by a page zone, or by a component with its own background such as the TOC bar. On this page you are looking at, the tinted band behind the title and the TOC bar are .ds-full bands.

The opening of the page, in a secondary band.

The thing the page is about, on the page ground.

Closing material, in a secondary band.
Relevant code
<div class="ds-container">
  <div class="ds-full ds-zone-secondary">               <!-- tinted: introduces -->
    <header class="ds-page-header">…</header>
  </div>
  <section>…</section>                                  <!-- page ground: the thing itself -->
  <div class="ds-full ds-zone-secondary">               <!-- tinted: supports -->
    <section>…</section>
  </div>
</div>
.ds-zone-secondary
Goes on a .ds-full band and gives it the tinted ground and its own top and bottom padding. A band that opens or closes the page runs to the container’s edge. The colour is the token --ds-zone-secondary-bg: the class is what you write, and the token is the colour the class applies, which changes in dark mode.
.ds-full
On a direct child of .ds-container. The child runs across all three columns, from edge to edge, and its padding brings its own content back in line with the centre column. It has no background of its own.
  • Dense pages do not use page zones. On an admin tool or a data view, where the reader needs to find and act on content quickly, a tinted band pushes the main content too far down the page. Separate content with spacing and headings instead.
  • Only a direct child can run full width. .ds-full works on children of .ds-container; nested deeper it does nothing.
  • Do not build a full-width band with negative margins and 100vw. 100vw includes the scrollbar, so a band built that way is wider than the page, and the page scrolls sideways on Windows and Linux. .ds-full measures the container instead, so it fits exactly.

Wide page

A dense internal tool can use a wider page: 1080px instead of 850px. Use it for tables and filters that do not fit the standard width, not for prose.

<main class="ds-container ds-container--wide">…</main>

.ds-container--wide sets the reading column to --ds-width-wide (1080px). Full-width bands follow it.

Rules

  • Use only the questions the content raises. When a page uses more than one layer, they stack in this order: navigation, then tabs, then filters.
  • One control of each kind per view. Never two rows of tabs, and never two filter bars.
  • No tabs inside a tab panel.
  • Filters apply to everything below them.
  • One Apply button per filter bar.
  • A number that changes a calculation is a setting, not a filter.
  • No breadcrumbs. See Header, Rules.