Use Playwright’s temporary screenshot stylesheet to hide the page scrollbar without changing your application CSS. Combine scrollbar-width: none with ::-webkit-scrollbar { display: none; }, and add fullPage: true when you need the entire document:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
path: 'screenshot.png',
fullPage: true,
style: `
html, body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
`,
});
await browser.close();
The style option applies CSS only while the screenshot is being made, so normal scrolling and production styles remain unchanged. If the bar belongs to an inner panel rather than the document, target that panel as well.
Hide the scrollbar while taking a screenshot
Playwright accepts stylesheet text through the style property of page.screenshot(). That is the safest place to hide a scrollbar for a capture because the rules are temporary. They are applied during the screenshot and then discarded.
Complete JavaScript example
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-without-scrollbar.png',
fullPage: true,
style: `
html, body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
`,
});
await browser.close();
fullPage: true captures the complete scrollable document instead of only the current viewport. Without it, the CSS still hides the visible bar, but the image contains only the viewport requested by the screenshot call.
#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
Why both CSS rules are included
scrollbar-width: none is the standard way to remove the visible scrollbar while leaving the element scrollable. The ::-webkit-scrollbar pseudo-element is used by WebKit/Blink-style engines. Combining them gives broader coverage than relying on either rule alone:
html, body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
These declarations affect appearance, not the page’s normal scrolling behavior. A user can still scroll, and Playwright can still scroll the document to assemble a full-page capture.
Target the element that actually scrolls
Hiding html and body removes the document scrollbar. Modern applications often put scrolling on a nested element instead, such as a results panel, modal body, or dashboard column. Apply the same rules to that selector:
await page.screenshot({
path: 'dashboard.png',
fullPage: true,
style: `
html, body,
.results-pane,
.modal-body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar,
.results-pane::-webkit-scrollbar,
.modal-body::-webkit-scrollbar {
display: none;
}
`,
});
If several nested containers can scroll, include each one that contributes a visible bar. Hiding only the outer document bar will not remove a scrollbar painted by an inner element.
Hide the bar without disabling scrolling
Use the paired scrollbar rules when the objective is a clean image while preserving the page’s behavior. The element remains scrollable even though no scrollbar is shown.
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
Do not copy this CSS into permanent product styles without another obvious scrolling mechanism. A hidden scrollbar can remove an important affordance and make content difficult to discover, especially for keyboard, touch, or mouse users.
When to use overflow: hidden instead
If the captured state must not scroll at all, inject overflow: hidden:
await page.screenshot({
path: 'fixed-state.png',
style: `
html, body {
overflow: hidden;
}
`,
});
This is not equivalent to merely hiding the scrollbar. overflow: hidden removes visible scrollbars and prevents ordinary scrolling, but overflowing content can be clipped. Content may still be brought into view programmatically or by focus scrolling. It can also change the available layout width, so use it only when clipping or a non-scrollable state is intentional.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Full-page screenshots and timing
Wait for the page state you intend to capture
Scrollbar styling does not wait for content. Load the page and any dynamic content before the screenshot:
await page.goto(url, { waitUntil: 'networkidle' });
await page.locator('.results-pane').waitFor();
await page.waitForTimeout(300); // only when a known animation needs to settle
await page.screenshot({
path: 'final.png',
fullPage: true,
style: SCROLLBAR_CSS,
});
Prefer a meaningful selector wait over an arbitrary delay. If the page lazy-loads images as it is scrolled, make sure the content is loaded before comparing captures; otherwise, differences may be attributed incorrectly to scrollbar CSS.
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.
Keep the stylesheet deterministic in visual tests
Define one shared constant and pass it to every assertion that needs the clean state:
export const SCROLLBAR_CSS = `
html, body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
`;
await expect(page).toHaveScreenshot('home.png', {
fullPage: true,
style: SCROLLBAR_CSS,
});
Applying the same CSS on every run avoids a test that sometimes includes a bar and sometimes does not. Keep the capture viewport, browser engine, device scale factor, fonts, and page state consistent as well.
Browser and rendering caveats
Scrollbar painting is environment-dependent. Operating-system settings, overlay-scrollbar preferences, browser engine, viewport size, and full-page capture behavior can all change whether a bar is painted in the first place. A Windows 11 case reported with Playwright 1.50.1 showed a full-page screenshot without the body scrollbar. Therefore, a visual assertion should not assume that a scrollbar must exist before it is hidden.
For stable tests, assert the intended page content and layout rather than requiring a particular scrollbar pixel pattern. Run the same browser project and viewport in local and CI environments, and update baselines when the rendering environment intentionally changes.
Common failures and fixes
The scrollbar is still visible
- Wrong scroll owner: inspect the page and identify the element whose
scrollHeightexceeds its client height. Add that element’s selector to the injected CSS. - Only one engine-specific rule was used: include both
scrollbar-width: noneand the::-webkit-scrollbarrule. - The style was injected too late or not passed to the assertion: ensure the
styleproperty is on the exactscreenshot()ortoHaveScreenshot()call that creates the image. - A shadow-root component owns the bar: target the scroll container itself. Playwright’s screenshot stylesheet can pierce Shadow DOM, but a selector still has to match the relevant element.
fullPage does not include all content
- Confirm that
fullPage: trueis set on the screenshot call. - Wait for lazy-loaded images, infinite lists, and client-rendered sections before capture.
- If the application uses an inner scrolling panel, a full-page document screenshot will not automatically expand that panel. Capture the panel element or arrange the test state so the required content is present.
overflow: hidden cuts off content
That behavior is expected: hidden overflow can clip content and alter layout. Replace it with the two scrollbar-visibility rules when you need content to remain reachable and only want the bar removed.
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
The screenshot differs between local and CI
Check browser version, operating system scrollbar settings, viewport, device scale factor, fonts, animations, and network-loaded content. Do not make the test depend on the presence of a scrollbar; its painting is not guaranteed across environments.
Free tools Windows power users keep installed
One-click scans. No signup required.
Reusable helpers for a test suite
Centralize the style and screenshot options so production code and visual tests cannot drift:
const HIDE_SCROLLBARS = `
html, body {
scrollbar-width: none;
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
display: none;
}
`;
export async function cleanScreenshot(page, path, options = {}) {
await page.screenshot({
path,
fullPage: true,
style: HIDE_SCROLLBARS,
...options,
});
}
Call the helper only for images where a hidden bar is part of the expected presentation. Keeping the option opt-in prevents accidental differences in screenshots whose purpose is to test native scrolling UI.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you only need a rendered image or PDF and do not want to maintain a Playwright browser, ScreenshotNeo provides a website screenshot API and MCP server. Its capture pipeline accepts cookie and consent banners before removing more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
For a direct image request, see the ScreenshotNeo API documentation:
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchescurl -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,
)
r.raise_for_status()
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}`);
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, click-before-capture actions, selector hiding, waits for selectors, delays or network idle, request and resource blocking, custom headers and cookies, user-agent and Authorization values, timezone and geolocation, transparent backgrounds, resizing, configurable cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work to ease migration.
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.
An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients, so an AI agent can request captures directly.
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to try it.
FAQ
Does hiding the scrollbar disable page scrolling?
No. The scrollbar-width: none and ::-webkit-scrollbar rules hide the visual control while leaving the element scrollable.
Should I inject the CSS with page.addStyleTag() instead?
You can, but screenshot({ style: ... }) keeps the change scoped to one capture and automatically avoids modifying the page for later interactions.
Can I hide a scrollbar in an element screenshot?
Yes. Pass the same style while capturing the element, and target the element or its nested scroll container rather than only html and body.
Frequently Asked Questions
Does hiding the scrollbar disable page scrolling?
No. The temporary scrollbar rules remove the visual bar but preserve scrolling.
Can the same technique be used with Playwright screenshot assertions?
Yes. Pass the stylesheet through the assertion’s screenshot options and use the same deterministic CSS for every baseline.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Why does a full-page image still show a panel scrollbar?
The panel is an independent scroll container. Add its selector to the injected rules; hiding the document scrollbar cannot hide a bar painted by that panel.
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.

