Material Next
On this page

Overview

<mnw-device-frame> draws Google's device art around whatever you slot in, sized so the display is exactly the window in CSS pixels (1dp = 1px):

device Window Frame size
pixel_9_pro_xl (default) 430 × 957 469 × 992
pixel_9_pro_fold (open) 852 × 883 904.53 × 933.27
pixelbook_go 1218 × 720 1459.47 × 973.2

These are the devices of the WINDOWS presets (phone, fold, desktop), so ScreenHost and createMarketingEmbed() pick the frame from the window. Use the element directly for a custom composition: a store screenshot, a press image, a video frame.

Live demo

pixel_9_pro_xl, 430 × 957
pixel_9_pro_fold, 852 × 883
pixelbook_go, 1218 × 720
One sample screen per device, laid out for its window: bottom bar, rail, desktop.
<div class="frames-demo">
  <figure>
    <mnw-device-frame device="pixel_9_pro_xl"><div data-window="phone"></div></mnw-device-frame>
    <figcaption><code>pixel_9_pro_xl</code>, 430 × 957</figcaption>
  </figure>
  <figure>
    <mnw-device-frame device="pixel_9_pro_fold"><div data-window="fold"></div></mnw-device-frame>
    <figcaption><code>pixel_9_pro_fold</code>, 852 × 883</figcaption>
  </figure>
  <figure>
    <mnw-device-frame device="pixelbook_go"><div data-window="desktop"></div></mnw-device-frame>
    <figcaption><code>pixelbook_go</code>, 1218 × 720</figcaption>
  </figure>
</div>
import {createMarketingEmbed} from 'material-next-web-components/marketing.js';
import type {MaterialNextDeviceFrame} from 'material-next-web-components/marketing.js';
import {SCREENS} from '../sample-app/screens.js';

const embed = createMarketingEmbed({screens: SCREENS});

export default (root: HTMLElement) => {
  const dark = matchMedia('(prefers-color-scheme: dark)').matches;
  for (const frame of root.querySelectorAll<MaterialNextDeviceFrame>(
    'mnw-device-frame'
  )) {
    frame.tone = dark ? 'dark' : 'light';
    const screen = frame.querySelector<HTMLElement>('[data-window]')!;
    // Each window lays the app out for its size: bottom bar, rail, desktop.
    void embed.mount(
      screen,
      'notes',
      {},
      {window: screen.dataset.window, palette: 'captured'}
    );
  }
};

Usage

The slotted element is forced to the device's window size and corner radius, and the frame's mask (rounded corners, camera) is drawn over it. The slot stays in light DOM, so your page's CSS styles the screen.

Scale a frame with CSS zoom (or transform: scale()) on the element, not by resizing it: the art and the display keep their exact proportions.

Assets

The frames are images: device-frames/<device>/back.webp and mask.webp for the phones, land_back.png and land_shadow.png for the Pixelbook Go. Copy them into your public folder with npx mnw-marketing-assets public/material-next and they load from /material-next/; if the site is served from a subpath, call configureMarketingAssets({base}) first. See Assets.

API

Google's device art around a slotted app screen: the Pixel 9 Pro XL for phones, the Pixel 9 Pro Fold open for tablets, the Pixelbook Go for desktop windows. The slotted screen stays in light DOM, so the app's CSS applies.

<mnw-device-frame> properties
PropertyAttributeTypeDefaultDescription
devicedeviceDeviceName'pixel_9_pro_xl'Which device: pixel_9_pro_xl, pixel_9_pro_fold or pixelbook_go.
shadowshadowbooleantrueDrop shadow under the device.
tonetone'light' | 'dark''light'Page tone behind the device, which tunes the shadow.
<mnw-device-frame> slots
SlotDescription
DefaultThe app screen, sized to the device's window.

tone="dark" deepens the drop shadow for dark pages; it does not change the device. The Pixelbook Go uses its own shadow image instead of a filter.

Accessibility

  • The art is decorative (alt=""); the slotted screen is the content and stays interactive.

Limitations

  • Three devices only. Other device art can be drawn with your own element around the same screen.
  • The Pixelbook Go's glare layer is left out, so the screen stays as clear as on the phones.
mail