Page

import "@taprootio/espalier/page";

<esp-page>

Used to lay out standard page structure.

Examples

Resizable preview

Main, preview, and contextual help

Slots

<esp-page> has the following slots:

header

Global navigation content (typically an esp-header).

sidebar

Contextual navigation placed in the left aside.

right

Content to place in the right aside.

preview

Persistent preview content placed after the main surface and before help. It grows from --esp-page-preview-min-width to --esp-page-preview-max-width, starting at --esp-page-preview-default-width when that token is set. It starts at viewport top and gives its content an independent 100dvh vertical scroller. At either scroll boundary, wheel and trackpad motion chains back to the main document. Unlike flyout content, preview content is never replaced by the flyout request bus.

flyout

A transient esp-flyout panel that lives on the canvas after preview. Closed it costs no width; open it grows from --esp-page-flyout-min-width to --esp-page-flyout-max-width, starting at --esp-page-flyout-default-width when that token is set. It receives remaining flexible space after preview when no default is set, then docks as a width-competing right sidebar when no gutter exists and becomes an overlay drawer on small viewports. The persistent right aside and the transient flyout are complementary, not alternatives. A flyout opened with an anchor aligns to that trigger and stays in the same document scroll flow. When a preview is visible, its caret and non-interactive dotted bridge cross the preview back to the anchor, ending at a short thick marker on the preview/help seam.

Content to place in the footer. Slot esp-footer directly to receive the page's surface-alignment custom-property contract. A wrapper can preserve landmark semantics but does not receive that direct contract.

Default

The main page content. The main content region applies contain: inline-size so child components cannot push the content well wider than its grid column. In narrow mode, slotted children are constrained to max-inline-size: 66ch for optimal reading measure.

Attributes

<esp-page> has the following attributes:

kind

kind has a default value of "wide".

The layout mode of the page.

  • wide (default) — constrains the main content well to 1536px. Optimized for high-density dashboards and complex data grids.
  • narrow — constrains the main content well to 768px and applies a max-inline-size: var(--esp-measure, 66ch) reading measure. Optimized for long-form reading content.
  • full — no max-width constraint unless --esp-page-main-max-width is explicitly configured. Optimized for immersive canvases like maps or design tools and finite authoring workspaces that opt back into a cap.
  • site — the marketing-page shell (ESP0174): the main region always spans the full viewport width with no gutters, so slotted esp-section bands run edge to edge and center their own wells. The header and footer alignment contract is published from --esp-page-well-max-width instead of a main cap, so bar content, section wells, and footer content share one column. The sidebar/right rail slots are unsupported in this kind (a rail would offset the sections while the chrome keeps centering on the viewport, splitting the shared column) — a populated rail warns once.

align

align has a default value of "start".

Horizontal alignment of the content surface (left aside + main well + right aside) within the page once the viewport is wider than the content cap. The surplus width becomes styleable canvas gutters on the outer edges, weighted by this attribute.

  • start (default) — the surface hugs the leading edge; all spare width collects in the trailing gutter. This reproduces today's layout.
  • center — spare width is split evenly into both gutters, centering the surface.
  • end — the surface hugs the trailing edge; spare width collects in the leading gutter.

Has no effect when an unconfigured kind="full" or kind="site" leaves main unbounded, or on viewports narrower than the complete visible workspace cap.

contained

contained has a default value of false.

When set, the header and footer sit on the content surface — the same width as the left aside + main well + right aside — instead of spanning the full viewport. Combined with a styled canvas this frames the whole page as one contained band floating on the canvas, with a single continuous surface edge shadow running from the header through the content to the footer.

Below the cap there are no gutters, so a contained page renders identically to the default full-bleed chrome. Designed for header-position="normal" or "sticky"; a fixed header cannot be banded to the surface.

header-position

header-position has a default value of "normal".

Header positioning behavior for the header slot.

  • normal lets the header scroll with content.
  • sticky keeps the header stuck to the top after it reaches it.
  • fixed pins the header to the viewport and offsets page content.

fixed-menus remains as a compatibility alias for fixed.

fixed-menus

fixed-menus has a default value of false.

Compatibility alias for the original fixed header/sidebar behavior. Prefer header-position="fixed" for new code.

preview-open

preview-open has a default value of false.

Whether the persistent preview is logically open. The page may keep the preview hidden while space is unavailable; preview-visible reflects its actual presentation and the preview restores automatically when room returns.

preview-label

preview-label has a default value of "Preview".

Accessible name for the preview's complementary landmark.

preview-collapse-sidebar

preview-collapse-sidebar has a default value of false.

Allow a directly slotted, safely linked vertical menu/header pair to collapse to its burger/drawer presentation when preview needs more room.

workspace-resizable

workspace-resizable has a default value of false.

Expose accessible pointer and keyboard separators for the visible Main → Preview → Flyout/Help workspace seams and for the trailing edge of the last auxiliary pane when outer canvas is available. Preferred sizes remain on this mounted instance and are continuously re-clamped by page allocation.

preview-visible

preview-visible has a default value of false.

Whether preview content is currently rendered. Managed by the page's space negotiation; consumers should treat this reflected property as read-only.

preview-reclaiming

preview-reclaiming has a default value of false.

Whether preview is currently reserving width and allowing the main well to shrink toward --esp-page-main-min-width. Managed by the page.

intent

intent has a default value of undefined.

The element's intent — its meaning: neutral (no pin), or success, warning, danger, info — each pinned to its fixed status family (blue for info), retunable per theme via intents. On token-emitting controls a non-neutral intent pins the filled-action pair to that family, derived over the governing zone's theme; class-styled chrome (badges, callouts, status pills) opts out of inline emission and renders its treatment from CSS classes instead. An intent never repaints the surrounding zone, which is what contexts are for. Removing the attribute restores the element's own default intent.

context

context has a default value of undefined.

A theme-defined color zone. The selected context rebinds designer-facing roles and emits a complete, contrast-enforced semantic token table on this host for descendants to inherit.

Methods

<esp-page> has the following methods:

showPreview

Request the persistent preview without moving focus.

closePreview

Close the persistent preview without moving focus.

togglePreview

Toggle the persistent preview without moving focus.

AddDialog

Inject an element into a div with the highest z-index so dialogs are rendered on top of everything else.

traverseToClosest

Traverse up the DOM tree to find the closest element that matches the selector. This method is aware of shadow DOM boundaries and will traverse through them to find the element.

Events

<esp-page> emits the following events:

esp-page-workspace-resize

esp-page-workspace-resize is of type CustomEvent<PageWorkspaceResizeDetail>.

Fired while a pointer or keyboard interaction changes a preferred workspace allocation. separator identifies an internal seam ("main-preview", "preview-flyout", or "main-flyout") or the exposed trailing edge ("preview-end" or "flyout-end"). Bubbles and crosses the shadow boundary.

CSS Parts

<esp-page> has the following CSS parts:

wrapper

The page wrapper. It defaults to a grid with a height of 100vh. For the demo page, the height is set to 400px by styling the CSS part:

canvas

The two canvas gutter regions flanking the surface.

surface

The surface backdrop carrying the edge shadow/border.

preview

The persistent preview complementary landmark.

preview-content

The sticky wrapper around preview content.

main-preview-resize-handle

Separator between main and preview. Announces main's width and includes preview's changing width in its value text when main is capped.

preview-flyout-resize-handle

Separator between preview and in-grid flyout/help while preview is visible. Announces help's width.

main-flyout-resize-handle

The same physical seam while preview is hidden or closed: it then sits between main and in-grid help, sizes help directly against main, and reports separator: "main-flyout".

preview-end-resize-handle

The exposed trailing edge of preview while preview is the last in-grid auxiliary pane.

flyout-end-resize-handle

The exposed trailing edge of in-grid flyout/help while help is the last auxiliary pane.

Use align to place the surface within the page once it hits its cap, and the canvas tokens to style the gutters. A low --esp-page-max-width is set here only so the gutters are visible inside the narrow demo frame; the surface edge shadow is on by default.

CSS Properties

<esp-page> has the following CSS properties:

--esp-page-background

The background color of the page. Fills both the surface and the canvas gutters; the canvas tokens paint over it in the gutters only. Defaults to var(--esp-color-background).

--esp-page-main-min-width

Minimum width of the main content well while preview or in-grid help competes for space. Defaults to 30rem.

--esp-page-main-max-width

Maximum width of the main content well. Defaults from kind: 1536px (wide), 768px (narrow), or unbounded (full). An explicit value overrides every kind default, including full — except site, whose main region is always unbounded because sections own their wells. Surplus width beyond it becomes canvas gutters.

--esp-page-well-max-width

The shared content-column width in kind="site": the header and footer alignment contract and every esp-section well default to it. Defaults to 72rem.

--esp-page-max-width

Legacy fallback for --esp-page-main-max-width.

--esp-page-background-image

The background image to display behind page content. Defaults to none.

--esp-page-background-image-opacity

The opacity of the background image layer. Defaults to 1.

--esp-page-canvas-background

The background color of the canvas gutters (the outer regions revealed when the viewport exceeds the cap). Defaults to transparent, so gutters match the page until styled and narrow viewports are unaffected.

--esp-page-canvas-background-image

A background image for the canvas gutters, mirroring the page background-image knob. Defaults to none.

--esp-page-canvas-background-image-opacity

The opacity of the canvas gutter image layer. Defaults to 1.

--esp-page-surface-shadow

The box shadow drawn on the left and right edges of the content surface. On by default; casts into the gutters and is clipped away when the surface fills the viewport, so it only shows above the cap. Set to none to remove it.

--esp-page-surface-border

An optional border on the inline edges of the surface, for themes preferring a hairline over a shadow. Defaults to none (e.g. 1px solid var(--esp-color-border)). Combine with --esp-page-surface-shadow: none to switch the content frame from a drop shadow to a hairline, or turn both off for no frame.

--esp-page-main-background

The background of the main content well. Defaults to transparent (the well shows the page background). Set it to give the content well its own card color, or pair the transparent default with --esp-page-surface-shadow: none for content that floats directly on the page with no frame.

--esp-page-preview-background

Background of the persistent preview surface. Defaults to the main background, then the page background.

--esp-page-preview-border

Leading tear-off edge between main and preview. Defaults to 1px dotted var(--esp-color-border).

--esp-page-preview-shadow

Shadow cast from the preview's trailing edge. Defaults to the page surface edge shadow. Set to none for a flat additive surface.

--esp-page-preview-min-width

Minimum preview width. Defaults to 22.5rem (360px, a reasonable mobile-device surface).

--esp-page-preview-default-width

Initial automatic preview target, clamped between the preview minimum and maximum. When unset, the established preview-first flexible allocation remains in effect. A retained pointer or keyboard resize preference supersedes this target.

--esp-page-preview-max-width

Maximum preview width. Defaults to 48rem. Preview receives flexible trailing space before help grows.

--esp-page-flyout-min-width

Minimum in-grid help width. Defaults to 20rem.

--esp-page-flyout-default-width

Initial automatic in-grid help target, clamped between the help minimum and maximum. When unset, the established flexible allocation remains in effect. A retained pointer or keyboard resize preference supersedes this target.

--esp-page-flyout-max-width

Maximum help width and overlay drawer cap before the 85vw viewport cap. Defaults to 30rem.

--esp-page-resize-step

Arrow-key resize step. Defaults to 1rem.

--esp-page-resize-large-step

Shift+Arrow resize step. Defaults to 4rem.

--esp-page-resize-handle-hit-size

Transparent inline hit target centered on each dotted seam. Defaults to 2.75rem.

--esp-page-resize-focus-outline

Keyboard-focus line drawn along the focused seam, spanning the visible dotted edge up to one viewport height. Defaults to 2px dashed var(--esp-color-link).

--esp-page-resize-focus-shadow

Glow cast by the focused seam line, in the line's color. Defaults to 0 0 0.75rem var(--esp-color-link).

--esp-page-preview-width

Legacy fixed-width alias that pins both preview bounds.

--esp-page-flyout-width

Legacy fixed-width alias that pins both help bounds.

--esp-page-preview-min-main-width

Legacy fallback for --esp-page-main-min-width.

--esp-page-fixed-header-offset

Offset reserved for fixed headers. Defaults to var(--esp-header-height).

--esp-page-sticky-header-top

Top inset for sticky headers. Defaults to 0.

--esp-page-header-z-index

Z-index for fixed/sticky header regions. Defaults to 20.

--esp-field-background

Background color of the shared field shell. Defaults to var(--esp-color-layer-2).

--esp-field-border-color

Border color of the shared field shell. Defaults to var(--esp-color-border).

--esp-field-border-width

Border width of the shared field shell. Defaults to 1px.

--esp-field-text-color

Text color used inside the shared field shell. Defaults to var(--esp-color-text).

--esp-field-hover-bg

Hover background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-bg

Focus background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-shadow

Shadow color used for shared field focus treatment. Defaults to var(--esp-color-shadow).

Components API Guides Getting started Styling Espalier Browser support GitHub npm package Taproot I/O