Skip to content
Cloaked Design SystemLayout

Screen

A full-height route scaffold that paints the surface, applies safe-area insets, and hosts sticky header and footer chrome around a scrolling body. Chrome padding is fixed by the system; only the body's padding is authorable.

Implementation preview
COMPLETE STORYBOOK REFERENCE

Every example. In one place.

Explore every named example, including states, compositions, and theme variants.

13 stories
SELECTED EXAMPLE

Playground

Open controls
Playground selectedOpen canvas
Example sourcepackages/design-system/src/components/layout/Screen/Screen.stories.tsxExport Playground

Implementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.

Stories + source JSON ↗

Local specification source status: preview. Implementation preview pending sign-off.

A full-height route scaffold that paints the surface, applies safe-area insets, and hosts sticky header and footer chrome around a scrolling body. Chrome padding is fixed by the system; only the body's padding is authorable.

Design-owned component contract ↗Version 0.2.0-preview.1 · Implementation preview pending sign-off
Implementation API 13 entry points · source-derived preview

Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.

import { Screen } from '@cloakedinc/design-system';
ScreenScreenProps

packages/design-system/src/components/layout/Screen/ScreenRoot/ScreenRoot.tsx:17

PropTypePresenceNotes
safeAreaScreenSafeArea | undefinedOptionalAdds safe-area insets to padding edges. Defaults to `'both'`.Source default: 'both'
scrollboolean | undefinedOptionalWrap legacy children or `Screen.Body` in a scrollable container. Defaults to `true`.Source default: true
surface"page" | "surface" | undefinedOptionalBackground surface token. Defaults to `'page'`.Source default: 'page'
overscrollTopstring | undefinedOptionalColor continued into the top over-pull edge (pass a `var(--cds-*)` token). Defaults to the surface color.
overscrollBottomstring | undefinedOptionalColor continued into the bottom over-pull edge (pass a `var(--cds-*)` token). Defaults to the surface color.
fillboolean | undefinedOptionalFill the available height. Defaults to `true`.Source default: true
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
childrenReact.ReactNodeOptional
testIdstring | undefinedOptionalSelector for the screen root element; the slots carry their own.
padding0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalPadding on all four sides.
paddingX0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalHorizontal padding (left + right). Overrides `padding` on the X axis.
paddingY0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalVertical padding (top + bottom). Overrides `padding` on the Y axis.
paddingTop0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalTop padding. Overrides `paddingY` and `padding`.
paddingRight0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalRight padding. Overrides `paddingX` and `padding`.
paddingBottom0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalBottom padding. Overrides `paddingY` and `padding`.
paddingLeft0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalLeft padding. Overrides `paddingX` and `padding`.
Screen.HeaderScreenHeaderProps

packages/design-system/src/components/layout/Screen/ScreenSlots/ScreenSlots.tsx:31

PropTypePresenceNotes
safeAreaboolean | undefinedOptionalAdds top safe-area inset. Defaults to the parent `Screen.safeArea`.
inset"activity" | undefinedOptionalPresentation inset for a header that stands in for a navigation bar.
stickyboolean | undefinedOptionalKeeps the header visible above the body scroller. Defaults to `true`.Source default: true
childrenReact.ReactNodeOptional
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
testIdstring | undefinedOptionalSelector for the `<header>` element; chrome inside it takes its own.
Screen.Header.BarScreenHeaderBarProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:24

PropTypePresenceNotes
justifyScreenHeaderJustify | undefinedOptionalHorizontal distribution for header chrome.Source default: 'between'
childrenReact.ReactNodeOptional
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
testIdstring | undefinedOptionalSelector for the row element; chrome inside it takes its own.
Screen.Header.BrandScreenHeaderBrandProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:193

PropTypePresenceNotes
childrenReact.ReactNodeRequired
testIdstring | undefinedOptionalSelector for the brand mark wrapper, not the node passed as `children`.
Screen.Header.TitleScreenHeaderTitleProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:36

PropTypePresenceNotes
childrenReact.ReactNodeRequired
as"h1" | "h2" | "h3" | undefinedOptionalOptional heading level. Defaults to `h1`.Source default: 'h1'
variant"h4" | "h5" | undefinedOptionalType ramp entry. Defaults to `'h4'`; `'h5'` matches the native iOS bar's `.font(.headline)`.Source default: 'h4'
testIdstring | undefinedOptionalSelector for the heading element; nothing derives from it.
Screen.Header.ActionScreenHeaderActionProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:47

PropTypePresenceNotes
childrenReact.ReactNodeRequired
onPress(() => void | boolean) | undefinedOptionalCalled when the action is pressed. Return `false` to suppress the `safeBack` fallback.
safeBackboolean | undefinedOptionalTreat this action as a back affordance: if the header is still mounted after the transition, run `fallback`. Use on a text action ("Cancel", "Done") that is a screen's only way out.Source default: false
fallback(() => void) | undefinedOptionalLast-resort fallback when `safeBack` is set and the header remains mounted.Source default: reloadToRoot
fallbackDelayMsnumber | undefinedOptionalDelay before the `safeBack` check. Defaults to the Stackflow transition plus buffer.Source default: SAFE_BACK_FALLBACK_DELAY
hapticHapticFeedback | undefinedOptionalHaptic feedback for successful presses. Defaults to `true` (`light`).Source default: true
testIdRootstring | undefinedOptionalHeader test ID root used to derive `${testIdRoot}-${slot}`.
slot"right-action" | undefinedOptionalHeader action slot used for derived test IDs.
testIdstring | undefinedOptionalSelector for the action element. Overrides the `${testIdRoot}-${slot}` derivation.
Screen.Header.BackButtonScreenHeaderBackButtonProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:133

PropTypePresenceNotes
onBack() => void | booleanRequiredCalled when the back button is pressed. Return `false` to suppress the fallback.
fallback(() => void) | undefinedOptionalLast-resort fallback when the header remains mounted after the back transition.Source default: reloadToRoot
fallbackDelayMsnumber | undefinedOptionalDelay before the fallback check. Defaults to the Stackflow transition plus buffer.Source default: SAFE_BACK_FALLBACK_DELAY
labelstring | undefinedOptionalAccessible action label. Defaults to `Back`.Source default: 'Back'
glyph"arrow-left" | "close" | undefinedOptionalMark the back affordance draws. Defaults to `arrow-left`.Source default: 'arrow-left'
hapticHapticFeedback | undefinedOptionalHaptic feedback for successful presses. Defaults to `true` (`light`).
testIdRootstring | undefinedOptionalHeader test ID root used to derive `${testIdRoot}-back`.
testIdstring | undefinedOptionalSelector for the back button. Overrides the `${testIdRoot}-back` derivation.
Screen.Header.IconButtonScreenHeaderIconButtonProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:91

PropTypePresenceNotes
iconReact.ReactElement<any, string | React.JSXElementConstructor<any>>RequiredIcon element to render inside the header action.
labelstringRequiredAccessible action label.
onPress(() => void) | undefinedOptionalCalled when pressed. Without it the icon renders as a static mark, not a button.
hapticHapticFeedback | undefinedOptionalHaptic feedback for successful presses. Defaults to `true` (`light`).Source default: true
testIdRootstring | undefinedOptionalHeader test ID root used to derive `${testIdRoot}-${slot}`.
slotScreenHeaderIconButtonSlot | undefinedOptionalHeader icon slot used for derived test IDs.
testIdstring | undefinedOptionalSelector for the icon element. Overrides the `${testIdRoot}-${slot}` derivation.
Screen.Header.ProgressScreenHeaderProgressProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:161

PropTypePresenceNotes
activeSegmentnumber | undefinedOptional1-based; every segment up to and including it renders filled. Defaults to `1`.Source default: 1
totalSegmentsnumberRequiredHow many segments to render; values below `1` are treated as `1`.
testIdstring | undefinedOptionalSelector for the segment row. The segments themselves are hidden from assistive tech.
Screen.Header.TaskScreenHeaderTaskProps

packages/design-system/src/components/layout/Screen/ScreenHeaderChrome/ScreenHeaderChrome.tsx:178

PropTypePresenceNotes
brandReact.ReactNodeOptionalBrand/avatar mark.
childrenReact.ReactNodeRequired
testIdstring | undefinedOptionalSelector for the task row, covering both the mark and the label.
Screen.BodyScreenBodyProps

packages/design-system/src/components/layout/Screen/ScreenSlots/ScreenSlots.tsx:55

PropTypePresenceNotes
scrollboolean | undefinedOptionalWrap body children in a scrollable region. Defaults to the parent `Screen.scroll`.
layoutScreenBodyLayout | undefinedOptional`'grouped'` renders `Screen.Section` slabs edge to edge. Defaults to `'solid'`.Source default: 'solid'
safeAreaScreenSafeArea | undefinedOptionalAdds safe-area insets to body padding. Defaults to `'none'`.Source default: 'none'
bleedUnderTopChromeboolean | undefinedOptionalRuns content under chrome the host draws over the web view, instead of clearing it. For a body whose top edge is already spoken for: a hero that bleeds to it, a scroller the body does not own, or an in-flow `Screen.Header` above it. Everything else wants the default, which insets by the host's chrome and supersedes the top edge of `safeArea`.Source default: false
childrenReact.ReactNodeOptional
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptionalInline style override. When `scroll` is true this lands on the scroll container, not the padded inner scroll-content — so a `padding*` here has no effect; use the padding props.
testIdstring | undefinedOptionalSelector for the `<main>` element, which is the scroll container when `scroll` is true.
padding0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalPadding on all four sides.
paddingX0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalHorizontal padding (left + right). Overrides `padding` on the X axis.
paddingY0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalVertical padding (top + bottom). Overrides `padding` on the Y axis.
paddingTop0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalTop padding. Overrides `paddingY` and `padding`.
paddingRight0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalRight padding. Overrides `paddingX` and `padding`.
paddingBottom0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalBottom padding. Overrides `paddingY` and `padding`.
paddingLeft0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalLeft padding. Overrides `paddingX` and `padding`.
Screen.SectionScreenSectionProps

packages/design-system/src/components/layout/Screen/ScreenSlots/ScreenSlots.tsx:109

PropTypePresenceNotes
childrenReact.ReactNodeOptional
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
testIdstring | undefinedOptionalSelector for the `<section>` element; nothing derives from it.
padding0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalPadding on all four sides.
paddingX0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalHorizontal padding (left + right). Overrides `padding` on the X axis.
paddingY0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalVertical padding (top + bottom). Overrides `padding` on the Y axis.
paddingTop0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalTop padding. Overrides `paddingY` and `padding`.
paddingRight0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalRight padding. Overrides `paddingX` and `padding`.
paddingBottom0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalBottom padding. Overrides `paddingY` and `padding`.
paddingLeft0 | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56 | 64 | 72 | 80 | 96 | 120 | 240 | undefinedOptionalLeft padding. Overrides `paddingX` and `padding`.
Screen.FooterScreenFooterProps

packages/design-system/src/components/layout/Screen/ScreenSlots/ScreenSlots.tsx:123

PropTypePresenceNotes
safeAreaboolean | undefinedOptionalAdds bottom safe-area inset. Defaults to the parent `Screen.safeArea`.
stickyboolean | undefinedOptionalKeeps the footer visible below the body scroller. Defaults to `true`.Source default: true
childrenReact.ReactNodeOptional
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
testIdstring | undefinedOptionalSelector for the `<footer>` element; controls inside it take their own.

Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.

Overview

Full-height route scaffold. Use it as the outermost element of a routed screen: it paints the page surface, applies safe-area insets, and hosts sticky Screen.Header / Screen.Footer chrome while Screen.Body owns the scroll.

When to use

Reach for Screen as the top-level wrapper of a routed view — anything that needs a header, a scrolling body, a pinned footer action, or device safe-area handling. Compose the header from the Screen.Header.* sub-parts (Bar, Title, Brand, Task, BackButton, IconButton, Action, Progress).

  • A detail, modal, or standalone screen that just needs a centered surface without route chrome? Use Background.
  • Laying out content inside a Screen? Use VStack / HStack / Grid.

Chrome padding is fixed

Screen.Header and Screen.Footer take no padding props. The header is 20 / 12 / 8 and the footer is 20 / 16 / 16, on every route, and a padding on the Screen root reaches only the body. Only Screen.Body is authorable, because body content genuinely varies — sectioned lists, full-bleed heroes — while chrome does not.

The props used to exist and every value in them drifted: one app settled on 12 / 8, another copy-pasted 16 / 12 into thirteen files, two chat headers inset their icons to 12 while their own body sat at 20, and seven headers shipped with no paddingX at all, flush to the screen edge.

Screen.Header inset="activity" is the one sanctioned variation: it swaps the 12 top for 32, for a Stackflow activity that renders a header with no Screen root above it and no navigation bar to sit under.

<Screen.Header inset='activity' testId='pack-details-header'>
    <Screen.Header.Bar justify='start'>
        <Screen.Header.BackButton onBack={pop} />
        <Screen.Header.Title>Pack details</Screen.Header.Title>
    </Screen.Header.Bar>
</Screen.Header>

For a bespoke host alignment — a header that must line up with a floating control the app draws outside React — the documented last resort is the slot's style prop, which lands after the constant. Reach for it only when a real host constraint outranks the system box, and say so in a comment.

Overscroll edges

The over-pull (rubber-band) region continues the color of whatever sits at that edge, so a full-bleed footer or colored hero doesn't break into a flat gray bounce. Set the edge color with overscrollTop / overscrollBottom (pass var(--cds-*) tokens) to match the content there — e.g. a colored hero at the top, or a FaqCarousel fullBleed band's var(--cds-feature-<tone>-backdrop) at the bottom. The effect is only visible while bouncing on a touch device.

Solid and grouped bodies

Every screen is one of two shapes, and layout is the only thing that picks between them:

  • solid (default) — children flow down one continuous surface inside the page gutter.
  • grouped — the grouped-list rhythm. The body drops its gutter, each Screen.Section paints the surface, and the fixed 16px gap between two sections takes the page color. The gap is not a prop — a tunable one re-opens the drift this closes.

Sections paint and position only. They add no inline padding, because content already self-pads to the page gutter (SectionHeader and List.Item both inset 20px). A section that insets its own children makes them double-inset.

The page color is a separator, never a ground. Only the gap between two sections takes it; everything else the body holds keeps the screen surface — the inset the body reserves for a native bar, bottom tab-bar clearance, the slack a short screen leaves under its last section, and both over-pull edges. A grouped body gets that by painting a box that holds only the sections and nests inside the padded one, so no page color ever reaches the boundary of the scrolling content. There is nothing to pair on the Screen root, and no overscrollBottom to set.

Body background

Screen.Body's scroll content is opaque so the overscroll backdrop shows only in the over-pull edges. To give a scrolling body a custom background (e.g. a hero→page gradient), set --screen-scroll-bg on the body — a raw background on the body className is painted over by the scroll content and won't show. See PackDetailsView for the pattern.

Component specification

$schema../../../specs/component-spec.schema.json
Parts
Id
root
Label
Root
Description
Full-height scaffold painting the surface. Structural container.
Required
true
Id
header
Label
Screen.Header
Description
Sticky top chrome slot.
Id
body
Label
Screen.Body
Description
Scrolling content slot that owns route padding.
Id
section
Label
Screen.Section
Description
Full-bleed content slab inside a grouped body. Paints and positions only; it adds no inline padding.
Id
footer
Label
Screen.Footer
Description
Sticky bottom chrome slot.
Id
bar
Label
Screen.Header.Bar
Description
Compact header row with justified chrome.
Id
brand
Label
Screen.Header.Brand
Description
App wordmark or brand mark.
Id
title
Label
Screen.Header.Title
Description
Route title; truncates to one line with an ellipsis.
Id
action
Label
Screen.Header.Action
Description
Text action in the header.
Id
back-button
Label
Screen.Header.BackButton
Description
Safe back button.
Id
icon-button
Label
Screen.Header.IconButton
Description
Icon-only header action.
Id
task
Label
Screen.Header.Task
Description
Partner mark plus active task label.
Id
progress
Label
Screen.Header.Progress
Description
Segmented header progress.
Allowed Design Choices
Variants
Route
Label
Route
Description
The single route-scaffold treatment.
Sizes
Surfaces
Page
Label
Page
Description
Paints the page background.
Surface
Label
Surface
Description
Paints the raised surface background.
Safe Areas
None
Label
None
Top
Label
Top
Bottom
Label
Bottom
Both
Label
Both
Insets
None
Label
None
Description
Standard route header: 12 top, 8 bottom.
Activity
Label
Activity
Description
Deeper 32 top inset for a Stackflow activity that renders a header with no Screen root above it and no navigation bar to sit under.
Variants
Id
route
Label
Route
Description
Full-height route scaffold.
Platforms
  • ios
  • android
  • web
SizesNone specified
Measurements
Id
chrome-padding
Label
Header and footer padding
Kind
exact
Token
--cds-space-20
Value
20
Unit
px
Applies To
  • header
  • footer
Notes
Fixed, not authorable: the horizontal gutter is 20 on both slots, the header is 12 top and 8 bottom (32 top under inset="activity"), and the footer is 16 top and bottom. Callers cannot set it, and a Screen padding does not reach it. Contrast with content-padding, which is example-only because the body genuinely varies.
Id
content-padding
Label
Body content padding
Kind
example-only
Token
--cds-space-20
Value
20
Unit
px
Applies To
  • body
Notes
Representative value: body padding is author-configurable and accepts any step on the spacing scale. 20 is the value rendered and verified by the slot-geometry story.
Layout
Alignment
Header and footer are sticky and full-width; the body fills the remaining height and scrolls.
Flow
A column: sticky header chrome, a scrolling body, and sticky footer chrome. A body set to layout="grouped" stacks Screen.Section slabs split by page-colored separators instead of flowing children inside the page gutter.
Notes
  • Chrome padding is a system constant, so the header and footer boxes are identical on every route; only Screen.Body accepts padding props. A bespoke host alignment goes through the slot's style prop.
  • Use Background when a detail or modal screen just needs a centered surface without route chrome.
  • layout picks between the two screen shapes. "solid" flows children down one continuous surface inside the page gutter. "grouped" is the grouped-list rhythm: the body drops its gutter, each Screen.Section paints the surface, and the 16px gap between two sections takes the page color as a separator. Sections paint and position only — content self-pads to the page gutter, as SectionHeader and List.Item already do. A section that insets its own children makes them double-inset.
  • The page color is a separator, never a ground. Everything else a grouped body holds keeps the screen surface: the inset reserved for a native bar, bottom tab-bar clearance, the slack a short screen leaves under its last section, and both over-pull edges. Nothing needs pairing on the Screen root.
Typography And Color
Typography
Label
Title
Description
Screen.Header.Title uses the h1 ramp by default.
Token
--cds-type-h1-size
Colors
Label
Page surface
Description
The page surface paints the route background.
Token
--cds-bg-page
Label
Raised surface
Description
The surface option paints the raised background.
Token
--cds-bg-surface
Label
Text
Description
Route content uses primary text.
Token
--cds-text-primary
States
Id
scroll
Label
Scroll
Description
The body scrolls under sticky chrome (the default).
Id
no-scroll
Label
No scroll
Description
scroll=false for short fixed routes.
Id
surface
Label
Surface
Description
Uses the raised surface background.
Behavior
Label
Sticky chrome
Description
Screen.Header and Screen.Footer stay pinned while Screen.Body scrolls.
Label
Safe area
Description
safeArea adds device insets on top of the configured padding, propagated to slots.
Label
Fixed chrome box
Description
Screen.Header and Screen.Footer own their padding. The parent Screen padding reaches only the body.
Label
Under host chrome
Description
Screen.Body always clears chrome the host draws over the web view, reading --cds-safe-area-top-chrome. It takes the larger of that and the device inset rather than stacking them, and collapses to zero where the host draws no chrome. bleedUnderTopChrome drops it for a body whose top edge is already spoken for — a bleeding hero, a scroller the body does not own, or an in-flow Screen.Header above it.
Label
Host chrome frost
Description
The Screen root draws a progressive blur the height of that same inset, so content reads as passing under the host's bar. The blur is strongest at the top and fully clear by the band's bottom edge, so content at rest is untouched. The host publishes --cds-top-chrome-frost to turn it on, and leaves it off for a bar drawing no background of its own, since a screen meaning to run edge to edge wants no blur across it. Nothing on Screen configures it.
Accessibility
Label
Route structure
Description
Header, body, and footer keep a predictable landmark order for assistive tech.
Label
Safe insets
Description
Safe-area insets keep chrome clear of the notch and home indicator.
Content Adaptation
Label
Header composition
Description
Compose the header from Bar, Title, Brand, Task, BackButton, IconButton, Action, and Progress sub-parts.
Label
Scroll control
Description
Disable scroll for short routes that never overflow.
Label
Title truncation
Description
Screen.Header.Title truncates long titles to a single line with an ellipsis instead of wrapping the header chrome.
Label
Activity inset
Description
inset="activity" on Screen.Header deepens the top inset for a Stackflow activity that stands in for a navigation bar.
Motion Haptics
Motion
Label
None
Description
Screen does not animate; slot chrome owns any motion.
Haptics
Label
Chrome haptics
Description
Header actions and the back button own their own haptics.
Platform Differences
Platforms
  • ios
Description
The scroll content is forced one pixel past the viewport so iOS WKWebView keeps momentum and rubber-band scrolling available on short screens.
Rationale
WKWebView only engages bounce when content exceeds the container, so short routes would otherwise feel dead at rest.
Implementation preview

This design-owned implementation is ready to try and review. It does not establish product approval. Imported specifications retain their original review status.

Inspect version 0.2.0-preview.1