Skip to content

Layout

Landmarks, containers & grid

Begin with document landmarks, then use a small composition layer where semantic HTML alone does not describe the layout.

Document landmarks

Direct body children header, main, and footer share a centered viewport. Its width is the smaller of the available width minus 2rem and --tty-container, which defaults to 72rem. Each landmark also receives its own vertical spacing, and the footer gets a top border.

<body>
  <header>
    <nav class="menu" aria-label="Primary navigation">
      <a href="/">Console</a>
      <a href="/status">Status</a>
    </nav>
  </header>
  <main>
    <h1>Deployment console</h1>
    <p>Choose a service to continue.</p>
  </main>
  <footer><small>Console version 1.0</small></footer>
</body>

Container

Use .container when a non-landmark element needs the same centered 72rem maximum viewport. It sets width and inline margins; it does not add padding, a surface, or a border.

Shared container width
<div class="container"><mark>Shared container width</mark></div>

Responsive grid

.grid creates equal, auto-fitting columns with a 1.5rem gap. It uses --tty-grid-min as the minimum column width, defaulting to 17rem, and collapses to the available width on smaller screens. Override the token locally, as this 14rem example does, without changing other grids.

Node 01

Healthy

Node 02

Healthy

Node 03

Deploying

<div class="grid" style="--tty-grid-min: 14rem">
  <article><strong>Node 01</strong><p>Healthy</p></article>
  <article><strong>Node 02</strong><p>Healthy</p></article>
  <article><strong>Node 03</strong><p>Deploying</p></article>
</div>

Overflow regions

.overflow-auto contains content that is wider than its parent. When the child is a table, tty.css also reserves room for the dotted offset treatment. Make a scroll region keyboard-focusable and label it when users may need to scroll without a pointer.

DeploymentEnvironmentRevisionStatus
api-2026-08-31Production Europe8f4c2a1Successful
<div class="overflow-auto" tabindex="0" role="region" aria-label="Deployment history">
  <table>
    <thead><tr><th scope="col">Deployment</th><th scope="col">Environment</th><th scope="col">Revision</th><th scope="col">Status</th></tr></thead>
    <tbody><tr><td>api-2026-08-31</td><td>Production Europe</td><td>8f4c2a1</td><td>Successful</td></tr></tbody>
  </table>
</div>

Focused content widths

Narrow

.narrow centers content at a maximum width of 32rem. It is useful for compact forms, prompts, and single-purpose panels.

Confirm deployment

Deploy revision 8f4c2a1 to production?

<article class="narrow"><h3>Confirm deployment</h3><p>Deploy revision 8f4c2a1 to production?</p></article>

Reading

.reading centers long-form content at a maximum width of 56rem. On an article it also opens the header treatment, restores display headings, removes paragraph line-length caps, and simplifies to an unframed layout below 44rem.

Incident report

Updated 31 August 2026

The service recovered after the queue drained. This report records the sequence of events and the follow-up work.

<article class="reading">
  <header><h1>Incident report</h1><small>Updated 31 August 2026</small></header>
  <p>The service recovered after the queue drained. This report records the sequence of events and the follow-up work.</p>
</article>

Terminal treatment

.terminal establishes positioning and adds the same dotted offset treatment used by framed components. It does not supply its own border, padding, or background, so pair it with content that already provides the desired frame.

$ tty deploy --production
Deployment queued.
<div class="terminal"><pre><code>$ tty deploy --production
Deployment queued.</code></pre></div>

Groups

.group lays out separate actions as a spaced flex row that wraps when needed, preserving each button's normal shadow. It stacks below 44rem; add .inline to retain a horizontal layout and spread items apart, still wrapping when space runs out. [role="group"] presents connected semantic controls with collapsed adjacent borders and no individual button shadows; it requires an accessible name from aria-label or aria-labelledby. Below 44rem, the connected controls stack vertically and remain joined.

Compact optionChange

<div class="group">
  <button type="button">Preview</button>
  <button type="button" class="secondary">Cancel</button>
</div>
 <p class="group inline"><span>Compact option</span><a href="#">Change</a></p>
 <div role="group" aria-label="Deployment actions">
  <button type="button">Deploy</button>
  <button type="button" class="contrast">Rollback</button>
</div>