Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsUse page.screenshot({ style: '...' }) when CSS should affect one direct screenshot, page.addStyleTag() when you want to inject a stylesheet before capture, and stylePath with expect(page).toHaveScreenshot() for Playwright Test assertions. The screenshot and assertion styling options were added in Playwright v1.41, so an older installed version may reject them.
Choose the right CSS approach
| Workflow | API | Best use |
|---|---|---|
| One direct screenshot | page.screenshot({ style }) |
Apply CSS text only while the screenshot is captured. |
| Page preparation | page.addStyleTag({ path, content, or url }) |
Insert a stylesheet into the page, then capture it or perform other actions. |
| Playwright Test visual assertion | expect(page).toHaveScreenshot({ stylePath }) |
Use a stylesheet file with snapshot comparisons. |
These APIs are documented in the Playwright Page reference and PageAssertions reference. Keep the capture-specific stylesheet separate from production styles so a test cannot accidentally change application behavior.
Apply CSS directly with page.screenshot
The style option accepts CSS text. Playwright applies it while making the screenshot, which is ideal for hiding cookie banners, timestamps, ads, animation artifacts, or other elements that should not appear in an image.
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
path: 'page.png',
fullPage: true,
style: `
.cookie-banner, .live-chat { display: none !important; }
.timestamp { visibility: hidden !important; }
`,
});
await browser.close();
Use display: none when the element and its layout space should disappear. Use visibility: hidden when preserving its dimensions prevents surrounding content from moving. The !important flag is often necessary because site styles may have equal or greater specificity.
Target one component instead of the whole page
Prefer stable, narrow selectors such as [data-testid="live-chat"] or a component class. A broad rule like div { display:none } can remove content you need and produce a misleading image. You can also change colors, dimensions, and text visibility:
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
await page.screenshot({
path: 'dark-clean.png',
style: `
body { background: #111 !important; color: #eee !important; }
.debug-panel { display: none !important; }
.updated-at { opacity: 0 !important; }
`,
});
Full-page, clipped, and element captures
CSS is applied regardless of whether you capture the viewport, the full page, a clip rectangle, or a locator. For a single component, locate it and use its screenshot method:
const card = page.locator('[data-testid="pricing-card"]');
await card.screenshot({
path: 'card.png',
style: '.badge { display: none !important; }',
});
If a hidden element changes page height, take a full-page capture after the style has removed it and verify that lazy-loaded content has appeared before saving the file.
Inject a stylesheet with page.addStyleTag
Use addStyleTag when the stylesheet should be inserted into the page before capture or reused across several actions. The API can add CSS text, a local file, or a URL. Relative paths are resolved from the current working directory.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.addStyleTag({ path: './screenshot.css' });
await page.screenshot({ path: 'styled.png', fullPage: true });
await browser.close();
screenshot.css might contain:
.cookie-banner,
.live-chat,
.newsletter-modal {
display: none !important;
}
video,
[data-animated="true"] {
animation: none !important;
transition: none !important;
}
Content and URL forms
await page.addStyleTag({
content: '.watermark { opacity: 0 !important; }',
});
await page.addStyleTag({
url: 'https://cdn.example.com/test-capture.css',
});
Wait for the returned promise before taking the screenshot. If a remote stylesheet is blocked by CSP or network policy, use content or a local path instead.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Use stylePath with Playwright Test snapshots
For visual regression tests, pass a stylesheet file to toHaveScreenshot. This option belongs to the Playwright Test runner, not the standalone Page API.
import { test, expect } from '@playwright/test';
import path from 'node:path';
test('stable home page', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot({
stylePath: path.join(__dirname, 'screenshot.css'),
});
});
You can configure the same stylesheet for all assertions:
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
stylePath: './tests/visual/screenshot.css',
},
},
});
The visual comparison guide describes this pattern at playwright.dev/docs/next/test-snapshots. Assertion styles pierce Shadow DOM and apply to inner frames, so selectors can reach volatile content inside those boundaries. Scope selectors carefully: hiding an entire iframe or shadow-root subtree can conceal a real regression.
How the assertion stabilizes images
toHaveScreenshot waits for two consecutive screenshots to match before comparing the final image with the stored snapshot. That makes it more tolerant of layout settling, but it does not make changing data deterministic. Freeze clocks, mock API responses, or hide only known volatile fields.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Control animations, caret, and scale
CSS alone is not a complete visual-stability strategy. Direct Page screenshots allow animations by default, while toHaveScreenshot disables them by default. With animations disabled, finite animations are fast-forwarded to completion and infinite animations are canceled at their initial state, then resumed afterward.
await page.screenshot({
path: 'stable.png',
animations: 'disabled',
caret: 'hide',
scale: 'css',
});
animations: Set'disabled'when motion can change pixels between runs.caret: The default is hidden; keep it hidden for text-field snapshots unless the caret is part of the requirement.scale: 'css': Produces one output pixel per CSS pixel and keeps files smaller and comparisons easier to review.scale: 'device': Uses device pixels and can create substantially larger images on high-DPI contexts.
Choose the same browser, viewport, device scale, fonts, color scheme, timezone, and locale in CI and on developer machines. Otherwise a correct CSS rule may appear to fail because text wrapping or rendering differs.
Practical CSS patterns
Hide volatile UI
const volatile = `
[aria-live],
.cookie-consent,
.chat-launcher,
. rotating-ad,
[data-testid="last-updated"] {
visibility: hidden !important;
}
`;
Replace example selectors with selectors from your application. Avoid hiding all aria-live regions if their visible content is part of the user experience you are testing.
Mask a value without changing layout
await page.screenshot({
path: 'account.png',
style: `
.account-number {
color: transparent !important;
background: #ddd !important;
border-radius: 3px;
}
`,
});
Use a pseudo-element overlay
await page.screenshot({
path: 'redacted.png',
style: `
.email { position: relative !important; color: transparent !important; }
.email::after {
content: 'redacted';
color: #222;
position: absolute;
inset: 0;
}
`,
});
Ensure the target has a positioning context and enough width for the replacement text. For security-sensitive data, do not treat a visual redaction as deletion from the DOM or network response.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Troubleshoot failed or misleading screenshots
“Unknown option: style” or “stylePath”
Upgrade the Playwright package used by the project to a version that supports the option; the references identify both options as added in v1.41. Check the installed dependency, not only a globally installed CLI, and verify the import is from the same package your tests execute.
The element is still visible
- Confirm the selector with
await page.locator('selector').count(). - Inspect whether the element is inside an iframe or Shadow DOM; assertion styles can cross those boundaries, while ordinary page selectors may need frame or shadow-specific handling.
- Increase specificity and add
!important. - Check that a later stylesheet or inline style is not restoring the property.
The page shifts after hiding a banner
Use visibility: hidden to preserve layout, or reserve a fixed space with a parent rule. If the banner is removed intentionally, wait for the page to finish reflowing before capture.
Snapshots differ only in animation or text
Disable animations, hide timestamps, freeze test data, and set a deterministic locale and timezone. Do not solve unexplained differences by increasing a pixel threshold until you know which content is changing.
Styles work locally but not in CI
Use a stylesheet path based on the test file or project root, confirm the file is checked into the repository, install identical browser binaries, and make sure custom fonts are available before the assertion runs.
Remote CSS fails to load
A URL passed to addStyleTag depends on network access and content-security policy. Prefer a local file or inline content for repeatable tests.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Performance, reliability, and maintenance
- Keep capture CSS short and component-specific; large global rules increase debugging time.
- Load the stylesheet once in a test fixture when many assertions use it, rather than injecting it before every assertion.
- Wait for the page state your screenshot represents: a selector, a known API response, fonts, and lazy images.
- Use a dedicated visual stylesheet under version control and review changes to it like test code.
- Do not hide failures such as an error banner, missing image, or loading spinner unless that behavior is explicitly outside the screenshot’s purpose.
For direct captures, the Page API reference documents full-page, clipping, format, animation, caret, and scale controls. For assertions, consult the PageAssertions reference alongside the visual comparison guide.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and whether the request was billed.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →One GET request returns PNG, JPEG, WebP, or a PDF. The API supports full-page and element captures, dark mode, device presets, custom CSS and JavaScript, clicks, waits, blocked requests, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed image links, asynchronous jobs, webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
See the ScreenshotNeo documentation for request options. The following cURL call captures a clean WebP:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
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 failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo’s Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account to get started.
Frequently Asked Questions
Can I use both style and addStyleTag?
Yes. Inject a reusable stylesheet with addStyleTag and pass a small, capture-only override through style; keep selector ownership clear so the two rules do not conflict.
Free tools Windows power users keep installed
One-click scans. No signup required.
Does stylePath work with plain page.screenshot?
No. stylePath is an option for Playwright Test’s expect(page).toHaveScreenshot(). Use style or addStyleTag with the Page API.
Will screenshot CSS alter my production site?
No, these rules are applied to the browser page used by the test or capture. They do not modify your deployed source, but they can alter what the test interacts with during that run.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

