Configuring viewport size and resolution in Headless Chromium is essential for consistent rendering across different devices and screen sizes. You can set these parameters using command-line flags or programmatically through automation libraries like Puppeteer, Selenium, or Playwright.
Key Concepts
- Viewport: The visible area of a web page within the browser window
- Window Size: The overall browser window dimensions
- Device Scale Factor: Controls pixel density for high-resolution displays
- Resolution: Combination of viewport size and pixel density
Command-Line Configuration
Basic Window Size
Set the browser window size using the --window-size
flag:
# Standard HD resolution
chromium-browser --headless --disable-gpu --window-size=1920,1080 https://example.com
# Mobile viewport
chromium-browser --headless --disable-gpu --window-size=375,667 https://example.com
# Ultra-wide display
chromium-browser --headless --disable-gpu --window-size=2560,1440 https://example.com
High-Resolution Displays
For HiDPI or Retina displays, combine window size with device scale factor:
# 2x pixel density (Retina)
chromium-browser --headless --disable-gpu \
--window-size=1920,1080 \
--force-device-scale-factor=2 \
https://example.com
# 1.5x pixel density
chromium-browser --headless --disable-gpu \
--window-size=1920,1080 \
--force-device-scale-factor=1.5 \
https://example.com
Puppeteer (JavaScript/Node.js)
Basic Viewport Configuration
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new', // Use new headless mode
args: [
'--disable-gpu',
'--disable-dev-shm-usage',
'--no-sandbox'
]
});
const page = await browser.newPage();
// Set viewport size
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1
});
await page.goto('https://example.com');
await page.screenshot({ path: 'desktop.png' });
await browser.close();
})();
Multiple Device Configurations
const devices = [
{ name: 'desktop', width: 1920, height: 1080, deviceScaleFactor: 1 },
{ name: 'tablet', width: 768, height: 1024, deviceScaleFactor: 2 },
{ name: 'mobile', width: 375, height: 667, deviceScaleFactor: 3 },
{ name: 'retina', width: 1920, height: 1080, deviceScaleFactor: 2 }
];
for (const device of devices) {
const page = await browser.newPage();
await page.setViewport(device);
await page.goto('https://example.com');
await page.screenshot({ path: `screenshot-${device.name}.png` });
await page.close();
}
Responsive Testing
// Test multiple breakpoints
const breakpoints = [320, 768, 1024, 1440, 1920];
for (const width of breakpoints) {
await page.setViewport({
width: width,
height: 1080,
deviceScaleFactor: 1
});
await page.goto('https://example.com');
await page.screenshot({
path: `responsive-${width}px.png`,
fullPage: true
});
}
Selenium WebDriver (Python)
Chrome Options Configuration
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def create_driver(width=1920, height=1080, scale_factor=1):
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument(f'--window-size={width},{height}')
if scale_factor != 1:
options.add_argument(f'--force-device-scale-factor={scale_factor}')
return webdriver.Chrome(options=options)
# Desktop configuration
driver = create_driver(1920, 1080)
driver.get('https://example.com')
driver.save_screenshot('desktop.png')
# Mobile configuration
mobile_driver = create_driver(375, 667, scale_factor=3)
mobile_driver.get('https://example.com')
mobile_driver.save_screenshot('mobile.png')
driver.quit()
mobile_driver.quit()
Dynamic Viewport Changes
# Change viewport size after initialization
driver.set_window_size(1366, 768)
driver.get('https://example.com')
driver.save_screenshot('laptop.png')
# Test multiple sizes
sizes = [(1920, 1080), (1366, 768), (1024, 768), (768, 1024)]
for width, height in sizes:
driver.set_window_size(width, height)
driver.refresh()
driver.save_screenshot(f'test-{width}x{height}.png')
Playwright (Multi-Browser)
Basic Configuration
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
deviceScaleFactor: 1
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'playwright.png' });
await browser.close();
})();
Device Emulation
const { devices } = require('playwright');
// Use predefined device configurations
const context = await browser.newContext({
...devices['iPhone 12'],
});
// Or create custom device configuration
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 2,
userAgent: 'Custom User Agent'
});
Common Viewport Sizes
Desktop Resolutions
const desktopSizes = [
{ width: 1920, height: 1080 }, // Full HD
{ width: 1366, height: 768 }, // HD
{ width: 1440, height: 900 }, // MacBook
{ width: 2560, height: 1440 }, // QHD
{ width: 3840, height: 2160 } // 4K
];
Mobile Resolutions
const mobileSizes = [
{ width: 375, height: 667 }, // iPhone SE
{ width: 375, height: 812 }, // iPhone X
{ width: 414, height: 896 }, // iPhone XR
{ width: 360, height: 640 }, // Android
{ width: 412, height: 915 } // Pixel
];
Best Practices
1. Choose Appropriate Sizes
// For web scraping, use common desktop sizes
await page.setViewport({ width: 1920, height: 1080 });
// For mobile testing, use actual device dimensions
await page.setViewport({ width: 375, height: 667, deviceScaleFactor: 2 });
2. Consider Page Load Times
// Wait for content to load after viewport changes
await page.setViewport({ width: 1366, height: 768 });
await page.waitForLoadState('networkidle');
3. Test Responsive Behavior
// Test how content adapts to different sizes
const sizes = [320, 768, 1024, 1920];
for (const width of sizes) {
await page.setViewport({ width, height: 1080 });
await page.waitForTimeout(1000); // Allow CSS transitions
// Test or capture content
}
4. Handle Scale Factors Correctly
// For high-DPI displays, adjust both viewport and scale factor
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 2 // Results in 3840x2160 effective resolution
});
Troubleshooting
Viewport Not Applied
- Ensure viewport is set before navigating to the page
- Some websites override viewport settings with CSS
- Check if the page uses responsive design
Screenshots Look Wrong
- Verify device scale factor matches your expectations
- Use
fullPage: true
for complete page screenshots - Consider CSS media queries affecting layout
Performance Issues
- Larger viewports require more memory
- High scale factors increase rendering time
- Use appropriate sizes for your use case
The viewport configuration affects how websites render and behave, making it crucial for consistent web scraping, testing, and screenshot capture across different scenarios.