ScreenshotNeo

BlogHow-to

How to Test Responsive Screenshots at 390 Pixel Width

Set a 390 CSS-pixel viewport, inspect the mobile layout, and automate screenshot comparisons with Playwright. Learn what the screenshot can—and cannot—verify.

By the ScreenshotNeo team4 October 20267 min read

To test a page at 390 pixels wide, set its viewport to 390 CSS pixels, load the page, and inspect or capture the result. For a repeatable automated check, configure Playwright with a 390-pixel viewport and compare screenshots against a baseline generated in the same browser environment. A 390-pixel check verifies one width; also inspect nearby widths and test on a real device when behavior depends on hardware or the mobile platform.

1. What “390 pixels wide” means

Responsive CSS layout is evaluated in CSS pixels. The screenshot file can have different physical pixel dimensions depending on its output scale: at CSS scale it has one image pixel per CSS pixel, while device scale can produce more image pixels for a high device-pixel ratio (DPR). The layout viewport should still be set to 390 CSS pixels when that is the condition you want to test.

Choose a height that matches the question you are checking. A viewport screenshot shows the visible area at that width and height. A full-page screenshot captures the page beyond the initial viewport, which helps review long-page layout and content, but does not by itself test scrolling interactions or lazy content that only appears after particular user actions.

2. Manual check in Chrome DevTools

  1. Open the page in Chrome and open DevTools.
  2. Enable Device Mode.
  3. Choose Responsive viewport mode and enter 390 for the width. Set a useful height for the view you want to inspect.
  4. Wait for the page to finish loading, then check the layout. Look for horizontal overflow, clipped or overlapping content, awkward line breaks, hard-to-reach controls, and whether the intended mobile layout is active.
  5. Capture the current viewport or a full-size page screenshot from DevTools, depending on whether you need to inspect only the visible area or the whole document.
  6. Inspect the media-query breakpoints shown in DevTools and check widths around the relevant transitions. Move the viewport across a breakpoint to verify both sides of the layout change.

Chrome DevTools supports custom responsive dimensions, media-query breakpoint inspection, and viewport or full-page screenshot capture. Its emulation is useful for layout review, but does not reproduce every physical-device characteristic. Chrome’s guidance is: “When in doubt, your best bet is to actually run your page on a mobile device.” See the Chrome DevTools Device Mode documentation.

3. Automated comparison with Playwright

Playwright Test can save a screenshot baseline and compare later runs to it with toHaveScreenshot(). The example below fixes the viewport at 390 by 844 CSS pixels, waits for the page to load, and compares a full-page screenshot. Replace the URL with your local or deployed page and keep the generated baseline under version control.

import { test, expect } from '@playwright/test';

test('mobile layout at 390 CSS pixels', async ({ page }) => {
  await page.setViewportSize({ width: 390, height: 844 });
  await page.goto('http://localhost:3000', { waitUntil: 'networkidle' });

  await expect(page).toHaveScreenshot('page-390.png', {
    fullPage: true,
    animations: 'disabled',
    scale: 'css',
    threshold: 0.2,
  });
});

For a viewport-only screenshot, remove fullPage: true. Playwright’s screenshot assertion can use CSS or device scale and supports a configurable color-difference threshold. The example uses CSS scale so image dimensions correspond to CSS pixels. A threshold of 0.2 is an example setting, not a universal pass/fail standard; choose comparison settings that suit the rendering noise and visual sensitivity of your project.

Playwright setup

Install Playwright Test in a Node.js project and add the test above as tests/mobile.spec.ts:

npm init playwright@latest

In the generated configuration, a project can set the viewport centrally:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    viewport: { width: 390, height: 844 },
  },
});

Then run the test and, when creating a new baseline, use Playwright’s update-snapshots option:

npx playwright test tests/mobile.spec.ts
npx playwright test tests/mobile.spec.ts --update-snapshots

Use baseline updates deliberately: review the changed image before accepting it, since updating snapshots can replace the expected appearance with a regression.

Use a consistent rendering environment

Screenshot output can vary with operating system, browser version, settings, hardware, and headless mode. Generate and compare baselines in a consistent environment, including the browser version and installed fonts. Avoid comparing a baseline made on one platform against a run from a different platform unless you have accounted for those rendering differences. See Playwright’s visual comparisons guidance, screenshot assertion options, and viewport and device emulation configuration.

4. Choose the screenshot scale and capture scope

Setting Use it when What to remember
390 CSS-pixel viewport You want to verify responsive CSS at the target layout width. Set this explicitly even if the captured image has more physical pixels.
scale: 'css' You want one screenshot pixel per CSS pixel. Useful for a CSS-pixel-sized visual baseline.
scale: 'device' You need output at the emulated device pixel scale. High DPR can make the image larger; it does not change the CSS viewport width.
Viewport screenshot You are checking the initial visible layout. Its height is the configured viewport height.
Full-page screenshot You need to inspect the document beyond the fold. It is not a substitute for testing scrolling, interactions, or real-device behavior.

5. What to inspect at 390px

  • Horizontal overflow: scroll or inspect the document width to find content extending beyond the viewport.
  • Clipping and overlap: check navigation, cards, images, dialogs, and fixed or sticky elements.
  • Text wrapping: review headings, buttons, labels, and long words or URLs for awkward breaks.
  • Reachability: make sure important controls remain visible and usable without being obscured.
  • Responsive state: confirm the expected navigation and layout changes are active at the target width.
  • Nearby widths: test just below and above relevant breakpoints. A passing 390-pixel screenshot does not prove the layout works at 375, 414, or every intermediate width.

Visual comparison catches changes in rendered output, but it does not decide whether the design is usable. Review differences and exercise interactive behavior separately.

6. Troubleshooting screenshot differences

Symptom Likely cause Fix
Large differences on every run The browser, operating system, fonts, device scale, or headless environment differs from the baseline run. Run baseline generation and comparisons in the same environment and pin the browser version used by the project.
Only text regions differ Fonts may not be installed or loaded before capture, or text rendering differs across platforms. Ensure the intended fonts are available and wait for page resources and fonts to finish loading before capturing.
Intermittent animation or blinking differences Animations, carousels, cursors, clocks, or other changing content are captured at different moments. Disable animations for the assertion where appropriate and stabilize or mask genuinely dynamic regions using Playwright’s supported screenshot options.
Screenshot is taller or shorter than expected The assertion captures the full page, content changes height, or the page has not settled. Use viewport capture for the visible region, wait for the relevant content to load, and investigate dynamic page height.
Image dimensions exceed 390 pixels The screenshot uses device scale, which can output device pixels rather than CSS pixels. Use scale: 'css' when you need one output pixel per CSS pixel; keep the viewport configured at 390 either way.
390px passes but another phone width breaks The test covers only one point in the responsive range. Add cases around the CSS breakpoints and widths important to your users.
Emulation looks correct but a phone behaves differently Emulation does not model every hardware, browser, or platform behavior. Reproduce on a physical mobile device for platform-dependent issues.

7. Performance, reliability, and maintenance

A single fixed viewport test is straightforward, but a full-page capture can include more content and take longer to render. Keep the test set focused on meaningful widths and breakpoints; add coverage where the design changes, rather than taking redundant screenshots at arbitrary intervals. Wait for the state your test actually cares about. Network idle can be inappropriate for pages with persistent network activity, in which case wait for a specific element or application-ready signal instead.

Visual baselines are reliable only when the rendering setup and page state are controlled. Use stable test data, deterministic content, consistent browser settings, and reviewed baseline changes. Treat screenshots as one signal: functional checks and real-device validation remain useful for behavior that pixels alone cannot establish.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Its API can capture a page at a custom viewport width; see the API documentation for parameters and configuration.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com", "width": 390},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
  width: '390',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Cookie and consent banners are accepted before capture, and 60+ known consent platforms, newsletter popups, and chat widgets are removed; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with page verdict and billing details in response headers. The MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

9. FAQ

Does a 390px screenshot represent a specific phone?

It represents the configured CSS viewport width. It is not proof that every phone with a similar screen behaves identically.

Should I use 390 or 393 pixels?

Use the width required by the device or layout condition you are checking. If you need broad coverage, test the widths and breakpoints that matter to your supported devices.

Can a screenshot test tell me whether controls are easy to use?

It can reveal visual problems such as clipping or overlap, but interaction and usability still need direct checks.