Cross-browser testing approaches and compatibility matrices to ensure consistent user experiences across all browsers.
90+
14+
90+
78+
90+
14+
11
14+
Support Levels: Full (β All features work), Partial (β οΈ Some limitations), None (β Major issues or not supported)
Data based on global browser usage statistics. Update support matrix based on your actual user analytics.
Systematic testing across different browsers and versions to ensure consistent functionality.
Internet Explorer 11 has limited and buggy CSS Grid support
Use CSS Grid with Flexbox fallbacks
@supports (display: grid) { /* Grid styles */ } and provide Flexbox alternative
CSS variables not supported in older browsers
Use PostCSS plugin to compile variables to static values
Provide fallback values: color: red; color: var(--primary-color);
ES2017 async/await not supported in older browsers
Use Babel to transpile to Promise-based code
Use Promise.then() chains as fallback
Fetch API not available in older browsers
Include fetch polyfill or use axios/XMLHttpRequest
Conditionally load polyfill: if (!window.fetch) { loadFetchPolyfill() }
IntersectionObserver API not supported
Use IntersectionObserver polyfill
Fall back to scroll event listeners with throttling
// playwright.config.ts
import { defineConfig } from '@playwright/test'
export default defineConfig({
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'edge', use: { ...devices['Desktop Edge'] } },
// Mobile browsers
{ name: 'mobile-chrome', use: { ...devices['Pixel 5'] } },
{ name: 'mobile-safari', use: { ...devices['iPhone 12'] } },
],
use: {
baseURL: 'http://localhost:3000',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
}
})test('button works across browsers', async ({ page, browserName }) => {
await page.goto('/components/button')
const button = page.locator('[data-testid="primary-button"]')
await expect(button).toBeVisible()
// Take browser-specific screenshot
await expect(page).toHaveScreenshot(`button-${browserName}.png`)
// Test functionality
await button.click()
await expect(page.locator('.success-message')).toBeVisible()
})@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
@supports not (display: grid) {
.container {
display: flex;
flex-wrap: wrap;
}
}// Feature detection utility
const supportsIntersectionObserver =
'IntersectionObserver' in window
const supportsFetch = 'fetch' in window
if (supportsIntersectionObserver) {
// Use IntersectionObserver
} else {
// Fallback to scroll events
}if (!window.fetch) {
Β Β await import('whatwg-fetch')
}<script src="https://polyfill.io/
v3/polyfill.min.js?features=fetch">
</script>import 'core-js/stable'
import 'regenerator-runtime/runtime'