Guides / Web

It Works in Chrome. Then Safari Enters the Room.

A feature working in Chrome does not mean it works on the web. Browser engines, permissions, layout rules and mobile behavior can turn a finished feature into a second debugging project.

PUBLISHED · UPDATED · 9 MIN

The feature was finished.

Chrome liked it. Android liked it. My local tests liked it. I refreshed the page, clicked every button I could find, and began experiencing that dangerous developer emotion known as confidence.

Then I opened Safari.

The button was there. The page looked normal. I tapped it. Nothing happened. No crash, no useful dialog, not even a dramatic red screen. Safari simply decided that today was not the day.

Welcome to cross-browser development.

“Works in Chrome” is not “works on the web”

A browser is not just a window that paints HTML. Behind it is a browser engine. Chrome and most Chromium browsers use Blink, Firefox uses Gecko, and Safari uses WebKit. They implement the same web platform, but release timing, security choices, platform rules and edge behavior can differ.

A paragraph rarely exposes those differences. Files, clipboard access, PWAs, touch input, media, storage, permissions and newer CSS are much better at finding them.

The standards are shared; the conditions are not always identical

Clipboard code can look wonderfully simple:

await navigator.clipboard.writeText(text);

In practice, the operation may also depend on HTTPS, document focus, a recent user gesture, permission state and whether the current browser version supports the exact API.

Capability detection is usually more durable than guessing from the browser name:

if (navigator.clipboard?.writeText) {
  await navigator.clipboard.writeText(text);
} else {
  showManualCopyFallback();
}

The browser name tells you what it calls itself. Feature detection tells you what it can actually do.

A narrow desktop window is not a real phone

Responsive mode in desktop DevTools is useful, but a real phone adds touch events, virtual keyboards, safe areas, browser chrome, viewport changes, file pickers, background suspension, permission prompts and tighter memory limits.

The history of 100vh is a good example. Mobile browser toolbars appear and disappear, changing the usable height. Modern CSS therefore gives us units such as dvh, svh and lvh. Apparently “how tall is the screen?” required multiple correct answers.

On iPhone, a different browser icon does not erase every platform rule

iOS browsers have historically operated under strong WebKit platform constraints. That means Chrome on an iPhone has not simply been the same Blink environment you use on Windows or Android. This matters for PWA behavior, files, Web Share, media, storage and background execution.

If Android Chrome works and an iPhone fails, do not immediately assume your JavaScript became haunted. Check the platform.

Safari is not always the villain

Some complaints about Safari are deserved. In other cases it exposes assumptions your code should not have made: autoplay will always work, clipboard access will always be granted, local storage will live forever, or every API exists everywhere.

A more useful question than “Why is Safari broken?” is “Which browser behavior did my code assume?” That question usually gets closer to the bug.

My minimum test now looks different

  1. Desktop Chromium.
  2. A real Android browser.
  3. Safari or a real iPhone.
  4. Narrow and landscape layouts.
  5. Keyboard, touch and virtual-keyboard behavior.
  6. Permission allowed and denied.
  7. A fresh session without old cached state.

Developers are very good at testing the giant green Allow button. Users have an inconvenient habit of choosing Don't Allow.

The goal is graceful survival, not identical behavior

Cross-browser support does not require every browser to behave pixel-for-pixel identically. It means the important task survives. If native sharing is unavailable, expose a copy link. If clipboard access fails, show manual copy. If installation is unsupported, let the site remain a normal website.

A feature with a fallback is still a feature.

A feature that only works in the browser currently open on the developer's laptop is a demo.

So when Chrome says everything is finished, celebrate.

Just do not deploy the champagne yet.

Safari has not entered the room.