#993
Viewport simulator
An interactive phone drawing with a device-shape selector, switches for collapsed browser bars and edge-to-edge drawing, a keyboard height slider and a keyboard resize mode, plus a table of what 100lvh, 100svh and 100dvh resolve to and how much of each is hidden.
Hand this to your AI. It names the exact library parts, timings and accessibility promises of this demo.
Build the "Viewport simulator" pattern (@codeatlasdev/ui demo #993, concepts/viewport) in my app.
Call get_demo({ ids: ["#993"] }) first and keep its structure. It needs @codeatlasdev/[email protected].
Use: Teaching why a full-height block must be a floor (min-height) and not a fixed height, and how safe areas and the virtual keyboard change the usable height.
Keep these library parts, with the props and tokens the demo uses:
- SegmentedControl, Switch, Slider from "@codeatlasdev/ui"
Behaviour to keep:
- `import { DEVICE_PRESETS, hiddenBy, type PresetName, viewportHeights } from './model';` computes the numbers; the model is pure and unit-tested
- `<SegmentedControl` with `aria-label="Device shape"` and `bind:value={preset}` offers four presets: narrow phone, typical phone, short phone, phone in landscape
- `<Switch bind:checked={collapsed} label="Browser bars collapsed (after scrolling)" />` and `<Switch bind:checked={edgeToEdge} label="Page draws edge to edge (viewport-fit=cover)" />`
- `<Slider bind:value={keyboard}` for the keyboard height (`step={10}`), plus a second `SegmentedControl` with `aria-label="Keyboard resize mode"` for `resizes-content` or `resizes-visual`
- A to-scale phone `div` with `role="img"` and an `aria-label`, drawn with CSS custom properties (`--w`, `--h`, `--bar`, `--vis`, `--kb`), and a `<table class="sim__table">` with a screen-reader caption listing 100lvh, 100svh, 100dvh and the usable height
Reduced motion: the demo handles it; keep that branch.
Keyboard: operable; keep the focus order and key handling.
Change only the copy and the data. Use the theme tokens (--ca-*), never raw colours. Library parts
- SegmentedControl
@codeatlasdev/ui - Switch
@codeatlasdev/ui - Slider
@codeatlasdev/ui
How it is built
- `import { DEVICE_PRESETS, hiddenBy, type PresetName, viewportHeights } from './model';` computes the numbers; the model is pure and unit-tested
- `<SegmentedControl` with `aria-label="Device shape"` and `bind:value={preset}` offers four presets: narrow phone, typical phone, short phone, phone in landscape
- `<Switch bind:checked={collapsed} label="Browser bars collapsed (after scrolling)" />` and `<Switch bind:checked={edgeToEdge} label="Page draws edge to edge (viewport-fit=cover)" />`
- `<Slider bind:value={keyboard}` for the keyboard height (`step={10}`), plus a second `SegmentedControl` with `aria-label="Keyboard resize mode"` for `resizes-content` or `resizes-visual`
- A to-scale phone `div` with `role="img"` and an `aria-label`, drawn with CSS custom properties (`--w`, `--h`, `--bar`, `--vis`, `--kb`), and a `<table class="sim__table">` with a screen-reader caption listing 100lvh, 100svh, 100dvh and the usable height
Related
Loading source.