Cross-browser Compatibility
Concept
The work of making a site look and behave the same across different browsers such as Chrome, Safari and Firefox.
Why it exists
A browser is the program that takes a web document and paints it on screen, and for years the same document came out differently in each one. Margins were calculated by different rules, some features existed in only one browser, and plenty of behavior didn't match what the standard said. A page built against one browser could come out in another with text overlapping or a button that refused to respond.
The whole problem compressed into one sentence: "it works on my machine." An engineer would check the page in their own browser and call it done, and someone on another browser would open it, screenshot the damage, and send it back. Neither of them was lying, and both were describing their own screen accurately. On one, the checkout button sat off the edge of the viewport. On the other, it was exactly where it belonged.
The response at the time was to write different code per browser. Branch after branch piled up — this browser gets this, that one gets that — until the code became hard to read, and every new browser release added another branch. Standards eventually settled and browsers came to follow them, which removed most of those branches without removing the problem. What remains is a difference of timing: which part of the standard each browser implemented, and when. Handling that difference is what cross-browser compatibility means today.
How it works
Rather than matching every browser, you decide the range you intend to match and then find and fill only the gaps inside it. Four steps.
- Set the support range. Open the traffic records, see which browsers real users actually arrive on, and draw a line. Dropping old versions that account for under one percent removes that much work. Leaving this decision unmade leaves a vague obligation to support everything.
- Check whether the features you want exist across that range. A new layout property in CSS or a new syntax in JavaScript lands in each browser at a different time. Looking up the per-feature support table is work that belongs before the code, not after it.
- Fill the gaps. Three methods: add a polyfill, which is code that supplies a missing capability; compile new syntax down to older syntax at build time; or let the page degrade to something simpler where support is absent. The third is the cheapest, and it's usually the right call. Corners rendering square instead of rounded can stay as they are. Checkout failing cannot. Deciding which bucket a gap falls into is a two-minute conversation that saves a day of work.
- Verify in real browsers. Resizing a window doesn't catch these problems, because each browser paints with a different engine and produces different results at identical widths. For the main flows, run an end-to-end test — a test that drives the whole user journey the way a person would — once per browser so the check happens automatically.
Step 1 is where the time actually goes. An engineering team can't set the support list alone. Whether to drop a browser used by three percent of visitors depends on who those three percent are, and if an enterprise customer's standard browser sits in that slice, the percentage doesn't decide anything. Sales and support usually know that before the traffic dashboard does, which is why the list gets agreed rather than calculated.
Where it shows up
The differences surface in a fairly predictable set of places.
- Form controls — anything where the browser supplies its own interface, like date pickers and file inputs, differs in appearance and in how it's operated. One browser opens a calendar; another offers a bare text field, which means a date typed as 03/04 is ambiguous in a way the calendar version never was.
- Height calculations — a region sized against the full viewport height ends up partly hidden behind a mobile address bar. This is how the button at the bottom gets cut off, and it shows up only on a real phone, never in a desktop window narrowed to phone width.
- Fonts and line breaking — the same font stack renders with slightly different letter spacing and line height, so a heading tuned to fit on two lines wraps onto three in one browser only.
- Media and permissions — features the browser gates by policy, like video autoplay or notification prompts, come with different conditions for being allowed.
- iPhone — every browser on iPhone has long drawn pages with the same engine, so a difference that comes from that engine survives switching apps.
At Pagedeck the sharpest version of this involved the first view of a shared document link. The screen Noa designed came out as intended in Chrome, while in Safari the body content was pushed below the fold and the first impression was an empty page. Shared links are exactly where first-time visitors arrive, so the difference turned into drop-off immediately. After Theo tracked down the cause, the team added a step: that one screen gets opened in three browsers before every release.
How it sounds at work
"Did you check this in Safari?"
Don't mark it done after looking at one browser.
"We're supporting the latest two versions."
A declaration of range — inside it we fix things, outside it we don't look.
"That feature isn't supported yet, so we need a polyfill."
Some browser on the list lacks the capability, and substitute code has to supply it.
When this comes up during pre-release checks, Pagedeck splits the findings in two. Anything that does nothing when clicked gets fixed on the spot; a two-pixel margin difference gets noted and left alone. Without that split the check grows without end, and the next release skips it entirely. A list of five blocking issues gets worked through; a list of forty mixed items gets ignored.
What people get wrong
The common belief is that modern browsers all follow the standard, so this work is finished. It sounds like a story about old browsers. What actually changed is the nature of the difference: browsers used to diverge by ignoring the standard, and now they diverge by implementing new parts of it on different schedules. The newer the feature, the wider the gap — so a frontend team that adopts new syntax quickly meets this more often, not less.
The other assumption is that a page should look identical everywhere. Framed that way, the work never ends. The real test isn't the same picture but the same capability. A slightly different shadow costs nothing, since nobody opens two browsers side by side to compare. A signup button that won't click, or a total hidden behind an overlapping element, is fatal even for one person. Two days spent matching pixels would serve the product better as two days spent verifying the main flows.
Where to go next
Last updated 2026-09-16