Page

A page places units on the grid: navigation, content and optional supporting areas, in one of six layouts. See the full-page Examples for all six.

A simple catalogue page

A page title, quiet count and a few aligned rows establish hierarchy.

A standard page

The sidebar layout: navigation on the left, a header and the work on the right. Every area is named.

<ds-page layout="sidebar" divided>
<ds-sidebar slot="nav" label="Projects"></ds-sidebar>
<ds-row slot="header" fill>…</ds-row>
<ds-list>…</ds-list>
</ds-page>

Every layout has the same five areas, so content moves between layouts without being rewritten. An area with nothing in it takes no room.

AreaPut it there withHolds
Headerslot="header"The page’s title and its main actions, along the top of the main area.
Navslot="nav"Navigation, or the list in List and detail. The leading column.
MainNo slotThe work itself.
Asideslot="aside"Properties or related things. Its own column in Inspector, under the main area elsewhere.
Footerslot="footer"Closing actions such as Save, along the bottom of the main area.

Every column is a whole number of squares. Between columns there are two squares, between areas down the page one, and one around the page.

LayoutLeading columnMainTrailing column
sidebar12 squaresThe rest—
split16 squaresThe rest—
inspector12 squaresThe rest12 squares
column—32 squares, centred on the grid—
centered—16 squares, centred on the grid both ways—
tiles—12-square tiles—

Below 30 squares of width every layout becomes one column, navigation first. The layout follows the width of its own container, not the window, so a page inside a panel stacks when the panel is narrow.

AttributeDefaultWhat it does
layoutsidebarsidebar, split, inspector, column, centered or tiles.
dividedfalseDraws a hairline between the columns.
measure—The width of the column or centered column, in whole squares.
fillfalseTakes its container’s full height; each column scrolls on its own.
viewfalseOutlines each area and names it, for inspection.
drawerfalseFolds the navigation into a drawer on a narrow page.
drawer-labelMenuThe menu button’s and drawer’s name, a translation key.

With drawer, the navigation folds away below 30 squares instead of standing above the work. A menu button stands in a one-square column before the header and opens the navigation over the whole screen, the same screen overlay the Header opens: focus stays inside it, Escape, its close button, a link or the page widening close it, and the page holds its scroll meanwhile. ds-page-drawer reports it opening and closing (detail.open); openDrawer() and closeDrawer() work it from code.

<ds-page layout="sidebar" drawer>
<ds-sidebar slot="nav" label="Projects"></ds-sidebar>
<h1 slot="header">Inbox</h1>
…
</ds-page>

A column or centered page is as wide as its measure: 32 squares and 16 by default. Set another in whole squares with measure:

<ds-page layout="column" measure="28">…</ds-page>

measure="28" is exactly 28 squares at every scale. A fraction rounds to the nearest square, and zero, a negative number or text is ignored, so the layout keeps its own width. The attribute wins over --ds-page-measure, which is the same width as a custom property for styles that cannot reach the element’s attributes; write it in squares too, never pixels: --ds-page-measure: calc(28 * var(--ds-unit)). --ds-page-nav, --ds-page-aside and --ds-page-tile set the other widths the same way.

Centring a column in the width it has can leave it on a half square, off the grid lines the rest of the page is drawn on. ds-page shares the room beside the column out and rounds it down to whole squares, so the column always starts and ends on a grid line. When that room is an odd number of squares, the extra square falls on the trailing side. With less room than the measure needs, the column takes the width it has and stays one square in from the edge.

Import the typed adapter. It renders <ds-page> with layout, divided, measure, fill, view, drawer and drawerLabel typed, so the product declares nothing of its own:

import { Page } from "./design/react/page";
<Page layout="column" measure={28} divided>
<h1 slot="header">Settings</h1>
…
</Page>

The adapter does not register the element: import 4-page/ds-page once in the browser entry, as for the other components. A product that writes <ds-page> directly instead needs a JSX.IntrinsicElements entry for it in its own declarations, because React does not know custom elements; the adapter replaces that entry. Sync 1 copies react/page.ts with the component when a product names page in its components.

Grid · Container · Sidebar · List · Row