v1.2.0
  1. ds
  2. Patterns
  3. App shell

App shell

Sidebar, sticky top bar and a grid of panels for consoles.

The frame for a console: the sidebar on the left, a sticky top bar with breadcrumbs and search, and the page. Inside the page, panels sit on a 12-column grid. It is what the ops dashboard, service, pipeline run and settings templates are built on; open one to see it at full size.

<div class="app">
  <nav class="sidenav" id="app-nav" aria-label="Workspace">…</nav>
  <div class="app-main">
    <header class="app-top">
      <button class="btn icon sm ghost app-menu" aria-controls="app-nav" aria-expanded="false" aria-label="Open navigation">…</button>
      <ol class="crumbs"><li>acme-prod</li><li aria-current="page">Overview</li></ol>
      <button class="kbtn">Search <kbd>⌘K</kbd></button>
    </header>
    <main class="app-body" id="main">
      <div class="app-head">
        <div><h1>Overview</h1><p>Production, last 24 hours.</p></div>
        <div class="btn-row">…</div>
      </div>
      <div class="app-grid">
        <section class="panel-box" style="--span:8">
          <header><h2>Requests</h2>…</header>
          <div class="pad">…</div>
        </section>
        <section class="panel-box" style="--span:4">…</section>
      </div>
    </main>
  </div>
</div>

Behaviour

  • The sidebar is sticky at full height and scrolls on its own; the top bar sticks over the page with the same blur as the site header.
  • Under 860px the sidebar leaves the grid and becomes a sheet. .app-menu appears in the top bar; add .open to the sidebar to slide it in, and close it on Escape or a click outside.
  • Panels span --span of 12 columns. Under 1100px nothing is narrower than half; under 860px every panel takes the full width.
  • A panel's direct child list, table or log loses its own border, so the panel frame is the only one.
ClassOnWhat it does
.appdivSidebar column and the main column, at least the viewport tall.
.app-maindivThe top bar and the page.
.app-topheaderSticky bar: .app-menu, .crumbs (takes the space), then tools.
.app-menubuttonOpens the sidebar sheet on small screens; hidden on large ones.
.app-bodymainThe page, with the gutter as padding and 1.25rem between blocks.
.app-headdivTitle block on the left, actions on the right. An h1 can hold a state glyph or badge.
.app-griddivTwelve columns. Children span --span (12).
.panel-boxsectionA panel: header with an h2 and tools, then .pad or a flush list, table or log.
Do
  • One h1 per page in .app-head; panels use h2.
  • Keep the panel count a screen can hold: six to eight.
  • Put the time range in the head, once, for every panel.
Don't
  • A second sidebar for sections. Use tabs, or a settings nav inside the page.
  • Panels that each pick their own time range.
  • Cards inside panels.