Components / More
DeviceFrame
A phone, tablet or browser window drawn in CSS around a screenshot, a video or a live demo. The screen keeps its ratio at any width and clips its content to its rounded corners.
When to useLink to "When to use"
- Landing pages: an app screenshot or a live demo shown on the device it runs on.
- Docs and store listings: a screenshot that needs context (a phone layout, a browser page).
Use something else when:
- the picture needs no device around it: Image, or AspectRatio for a video or an embed
- the content is a framed surface of the page itself: Card
UsageLink to "Usage"
import { DeviceFrame } from "@arshad-shah/cynosure";
<DeviceFrame>
<img src="/home.png" alt="The app's home screen" />
</DeviceFrame>
<DeviceFrame device="tablet" orientation="landscape" label="The editor on a tablet">
<img src="/editor.png" alt="" />
</DeviceFrame>
<DeviceFrame device="browser" url="example.com/pricing">
<PricingDemo />
</DeviceFrame>device is phone (default), tablet or browser. The frame is as wide as its container, up to a token width for a phone (288px) or a tablet (576px); set style={{ inlineSize: … }} for another width. Everything inside scales with it.
Browser windowLink to "Browser window"
The browser bar has three drawn dots and an optional url. The address is decoration: it is not a link and is not announced. Long addresses are cut with an ellipsis.
Orientation and ratioLink to "Orientation and ratio"
orientation="landscape" turns a phone or tablet: the screen's ratio is swapped and the camera moves to the left edge. A landscape device is as tall as its upright one is wide. ratio sets the screen's width ÷ height upright (phone 9 / 19.5, tablet 3 / 4, browser 16 / 10 by default); landscape uses its inverse.
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
device | The device drawn around the content. Default "phone". | DeviceFrameDevice | "phone" |
orientation | Which way a phone or tablet is held. The browser ignores it. Default "portrait". | "portrait" | "landscape" | "portrait" |
ratio | Width divided by height of the screen, as drawn in portrait (phone and tablet) or as is (browser). Landscape uses its inverse. Default: 9 / 19.5 for a phone, 3 / 4 for a tablet, 16 / 10 for a browser. | number | 9 / 19 |
url | Address shown in the browser bar (decoration: it is not a link and is not announced). Browser only. | string | |
label | Accessible name. With it the frame is a figure with this name; without it the frame is decoration and adds nothing to the accessibility tree, so the content keeps its own semantics. | string | |
safeArea | Phone only: keep the content clear of the camera island (below it upright, beside it turned), as an app keeps clear of a real phone's. By default live content is kept clear and a screenshot, video or canvas fills the whole screen (it has its own status bar); true or false decides for any content. | boolean | |
children | What the screen shows: a screenshot, a video or a live demo. Each child is stretched to the screen and clipped. | ReactNode | |
className | Added to the root element, for layout. | string | |
style | Layout only (width, margin, placement). The height follows from the width. Restyle through tokens. | CSSProperties |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
| Situation | Result |
|---|---|
| The container gets wider or narrower | The screen keeps its ratio; a phone's or tablet's bezel and corners scale with it |
| Content is bigger than the screen | It is clipped to the screen and its rounded corners |
| A child is an image or a video | It covers the screen (object-fit: cover) |
| Dark mode | A phone or tablet stays dark, with an edge line; the screen and the browser window follow the theme |
ratio is 0, negative or not finite | The device's own ratio is used |
- Decorative by default: without
labelthe frame is a plaindivand adds nothing to the accessibility tree. The content keeps its own semantics: give a screenshot itsalt; controls in a live demo stay focusable and usable. - Labelled: with
labelthe frame is afigurewith that accessible name. - Browser bar: hidden from screen readers. Put the address in
labelif it matters. - Right-to-left: the browser dots start the bar, on the right; the address still reads left to right. A phone's camera stays in the middle.
TouchLink to "Touch"
Nothing in DeviceFrame can be pressed. Controls in a live demo bring their own hit areas.
ThemingLink to "Theming"
Tokens: --cy-device-frame-bezel, --cy-device-frame-edge, --cy-device-frame-shadow, --cy-device-frame-screen, --cy-device-frame-phone-width, --cy-device-frame-tablet-width, --cy-device-frame-browser-radius, --cy-device-frame-browser-bar and --cy-device-frame-dot.
createTheme({ components: { deviceFrame: { bezel: "#3a3a3c", phoneWidth: "320px" } } });className and style are for layout only (width, margin, placement).
RelatedLink to "Related"
AspectRatio · Image · QRCode
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.