ScreenshotNeo

BlogHow-to

Can Chromatic test responsive layouts at custom screen sizes?

Yes. Chromatic can snapshot responsive layouts at custom viewport sizes; the setup depends on your test runner, and Storybook projects should use Modes.

By the ScreenshotNeo team4 October 20267 min read

Yes. Chromatic can test responsive layouts at custom screen sizes. In Storybook, define viewport modes and apply them to the stories you want to check. With Vitest, Playwright, or Cypress, set the viewport through the runner’s supported configuration or test context. Each selected size creates its own snapshot and baseline, so you can review responsive states independently.

This guide covers Storybook Modes, runner configuration, viewport limits, snapshot height, and common issues. Chromatic’s viewport documentation describes the runner integrations; its Modes viewport guide documents Storybook setup and limits.

1. Choose the configuration for your test setup

Setup Where to set the viewport Key detail
Storybook Define named viewports in Modes and select them with parameters.chromatic.modes. Modes support width and height, plus other global render settings such as theme and locale.
Vitest Configure the browser viewport or call page.viewport(width, height) in the test. The snapshot uses the viewport configured for the test.
Playwright Set a project viewport or use test.use({ viewport: { width, height } }). Test-level settings are useful when only selected tests need another size.
Cypress Set viewportWidth and viewportHeight in supported project or test options. Chromatic documents cy.viewport() as unsupported.

2. Configure custom sizes in Storybook

For new Storybook setups, use Modes. Define each named mode in .storybook/modes.js or .storybook/modes.ts. Then enable the desired mode on a story or component. The following is a JavaScript example:

// .storybook/modes.js
export const allModes = {
  tablet: { viewport: { width: 800, height: 600 } },
  phone: { viewport: { width: 390, height: 844 } },
};
// Example story file
import { allModes } from '../.storybook/modes';

export default {
  title: 'Layout/ResponsivePage',
  component: ResponsivePage,
  parameters: {
    chromatic: {
      modes: {
        Tablet: allModes.tablet,
        Phone: allModes.phone,
      },
    },
  },
};

Adjust the import path to match your project. The mode names are labels for the rendering conditions; the viewport dimensions determine the browser size. Apply modes at story level when only some stories need them, or at component level to share settings across that component’s stories. Project-level modes can also be configured in .storybook/preview.js or .storybook/preview.ts, but they multiply the review surface across the project.

Mode viewport dimensions can be an integer width, a width-and-height object, a width-only or height-only object, or integer strings with an optional px suffix. Keep each configured dimension between 200 and 2560 pixels, and keep snapshot area at or below 25,000,000 pixels. These limits are documented in the Chromatic Modes viewport reference.

Set height and decide whether to crop

A configured height sets the browser viewport height. By itself, it does not necessarily crop the snapshot to that height. Without a specified height, Chromatic captures to the rendered root container’s intrinsic height. If the desired output is clipped to the browser viewport, enable parameters.chromatic.cropToViewport:

parameters: {
  chromatic: {
    modes: {
      Phone: allModes.phone,
    },
    cropToViewport: true,
  },
}

With cropping enabled, content taller than the viewport is clipped; content shorter than the viewport is trimmed to its intrinsic height. Choose based on what the test is meant to validate: a full rendered page or the visible viewport region.

Legacy Storybook API

The older chromatic.viewports setting is documented as legacy. It supports widths only and is converted into modes during capture. Use Modes for new configurations, especially when height matters. See Chromatic’s legacy viewport guidance.

3. Set viewports in Vitest, Playwright, and Cypress

For test-runner integrations, the viewport is controlled by the runner’s supported configuration or test context. The exact project files vary with framework and runner versions, so use the configuration API for your installed runner version.

  • Vitest: set the viewport in the browser configuration, or configure it inside a test with page.viewport(width, height).
  • Playwright: set viewport: { width, height } on a project, or use test.use({ viewport: { width, height } }) for the relevant tests.
  • Cypress: configure viewportWidth and viewportHeight at project or supported test scope. Do not rely on cy.viewport() for Chromatic snapshots; Chromatic currently documents that call as unsupported.

Chromatic captures the DOM at the viewport size in which the test is configured to run. Consult the official integration examples for runner-specific details.

4. Choose sizes and snapshot coverage deliberately

Start with the widths where your layout changes behavior: for example, around your own CSS breakpoints and a representative narrow and wide viewport. Add a height when vertical clipping or fold behavior matters. There is no universal set of responsive sizes; derive them from the breakpoints and layout risks in your application.

Every selected mode/viewport combination receives an independent snapshot and baseline. This gives each responsive state its own comparison and approval, while increasing the number of snapshots reviewers must handle. Chromatic notes that project-level modes are not recommended in most cases because each viewport is reviewed independently. Prefer applying extra modes only to stories where those states provide useful coverage. See Modes for testing themes, viewports, locales, and more.

5. Limits and capture behavior

Behavior What to expect
Default viewport 1200 × 900 pixels when no viewport is specified.
Per-dimension range Each configured width or height must be a whole number from 200 to 2560 pixels.
Snapshot area Maximum 25,000,000 pixels.
Height without cropping Sets browser viewport size; the snapshot can still follow the rendered root’s intrinsic height.
Safari and Firefox image dimensions Capture limit of 32,767 image pixels in either dimension; Chromatic says it retries at device pixel ratio 1.0 if this limit is reached.
Legacy viewport setting chromatic.viewports is width-only and legacy; use Modes for new Storybook setups.

These constraints and behaviors come from the official viewport configuration documentation.

6. Troubleshooting

Symptom Likely cause Fix
The story looks unchanged at another width. The mode was defined but not selected on the story, or the selected setting is not reaching that story. Confirm the mode is included under parameters.chromatic.modes at the story or component level and check the viewport values.
The snapshot is much taller than the configured height. A viewport height sets browser size but does not by itself crop the captured content. Set parameters.chromatic.cropToViewport: true if a viewport-height crop is intended.
The lower part of the page is missing. Viewport cropping may be enabled, clipping content below the viewport. Disable cropping when the test should capture the full rendered height.
A configured viewport is rejected or capture fails at a large size. A dimension is outside 200–2560 pixels or the area exceeds 25,000,000 pixels. Reduce width or height and ensure their product is within the area limit.
Firefox or Safari capture hits an image-size limit. A dimension reaches the browser capture limit of 32,767 image pixels. Reduce the rendered image dimensions; Chromatic documents a retry at device pixel ratio 1.0 when the limit is reached.
Cypress snapshots do not reflect cy.viewport(). That call is currently unsupported by Chromatic’s documented integration. Set dimensions through supported viewportWidth and viewportHeight configuration or test options.
Review workload grows unexpectedly. Modes configured at project level create independent snapshots across many stories. Scope modes to the stories or components that need them.

7. Performance, reliability, and cost considerations

More viewport modes mean more independent snapshots to generate and review. Keep the set focused on meaningful breakpoints and states so the added coverage remains manageable. Large viewport areas are subject to the documented area limit, and extremely tall Safari or Firefox captures can encounter the documented image-dimension limit.

For reliable comparisons, keep the story’s content and rendering conditions consistent while varying the viewport. Modes can also represent themes, locales, and other global render settings, so combine conditions only when the resulting state is useful to validate. Each combination has its own baseline and approval. The research dossier does not specify Chromatic pricing or a capture-time benchmark, so no cost or speed estimate is given here.

8. Or skip the browser setup

If you need a website screenshot rather than a Chromatic visual-test baseline, ScreenshotNeo is a one-request screenshot API and MCP server. Its API can return PNG, JPEG, WebP, or PDF; see the ScreenshotNeo API docs for options and configuration.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

Replace YOUR_API_KEY with your key. In Node.js environments without Bun, save the response bytes using the file API provided by your runtime. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots; and the free plan includes 1,000 screenshots per month with no card, with paid plans starting at $5 for 3,000. These captures are useful for obtaining rendered images, but they do not create Chromatic’s per-story visual regression baselines.

Sign up for 1,000 free screenshots a month, with no card required.

9. FAQ

Can I test both width and height?

Yes. Storybook Modes accept a width-and-height viewport object. Runner integrations also support viewport dimensions through their configuration or test context.

Does setting a viewport height crop the page?

No. It sizes the browser viewport. Use cropToViewport when the snapshot should be clipped to that viewport height.

What happens if I do not specify a viewport?

Chromatic documents a default viewport of 1200 × 900 pixels.

Can Cypress change the viewport during a test with cy.viewport()?

Chromatic currently documents that call as unsupported. Configure the dimensions through supported Cypress viewport options instead.

Do all modes share one approval?

No. Each mode/viewport combination has its own snapshot and baseline for review.