Browser Rendering Differences and Common Issues

8 min read

The previous lesson explained why cross-browser testing matters. This lesson is the practical companion: what actually differs between Chrome, Firefox, and Safari at the level of CSS, JavaScript, and form controls — and how to spot the bugs those differences cause. By the end, you will recognise the recurring patterns that account for the bulk of cross-browser issues in production.

Where engines actually disagree

Cross-browser bugs cluster in four predictable areas. Most production incidents fall into one of these:

  • CSS layout and sizing. Flexbox, grid, viewport units, and any property that has been added in the last few years.
  • Form controls. Date, time, number, file, and select elements look completely different across engines, and their JavaScript APIs differ too.
  • JavaScript APIs. The Clipboard API, Intersection Observer, dialog elements, and many others shipped to different engines years apart and behave subtly differently even today.
  • Font rendering and antialiasing. Same font, same size, different number of pixels — text reflows by half a line and breaks careful layouts.

The same bug rarely appears in all three engines. It usually appears in one (most often Safari, sometimes Firefox), and your job as a tester is to know which engine to suspect first when something looks wrong on one browser only.

The same date input — three completely different experiences

The single best illustration of cross-browser drift is the humble <input type="date">. Same one line of HTML, three radically different user experiences.

<input type="date"> across the three major engines

Chrome (Blink)

  • Native HTML date picker

    Calendar drop-down, keyboard accessible, works as expected on desktop and Android.

  • Locale-aware format

    Displays dates in the user's locale (DD/MM/YYYY in UK, MM/DD/YYYY in US).

  • min/max attributes respected

    Visual disabling of out-of-range dates in the picker.

Firefox (Gecko)

  • Native picker — but different markup

    Calendar drop-down works, but the keyboard navigation order differs from Chrome.

  • Slightly different CSS reset

    Default border, padding, and focus ring differ from Chrome by a few pixels — enough to break a custom layout.

  • Step attribute behaves differently

    Stepping up/down with arrow keys jumps a different unit on Firefox in certain locales.

Safari (WebKit)

  • Plain text input on older macOS

    Until Safari 14.1, no calendar picker at all. The user types the date manually with no UI assistance.

  • iOS shows a wheel picker

    Mobile Safari renders a scrollable wheel — accessible but visually nothing like Chrome's calendar.

  • Format and timezone quirks

    Pre-16 versions parse `YYYY-MM-DD` strings using local time, leading to off-by-one date bugs.

Same HTML attribute. Three engines. One radically broken experience on a billion devices. This is the texture of cross-browser bugs — small, easy to miss in code review, and obvious only if you actually open the page on each engine.

CSS differences worth knowing

A handful of CSS issues recur often enough to memorise:

  • 100vh on iOS Safari. The viewport unit includes the URL bar, so a "full screen" container is taller than the visible area. The dvh and lvh units fix it on newer Safari but tested products often still use plain vh.
  • Scrollbar styling. Chrome and Edge support ::-webkit-scrollbar; Firefox uses scrollbar-width and scrollbar-color; Safari supports webkit pseudos partially. A "custom scrollbar" almost always means three different visual outcomes.
  • <select> styling. No engine lets you fully restyle the open dropdown. Custom-styled selects look perfect when closed and revert to the engine default when open. Safari is the most aggressive about ignoring custom styles.
  • Form element defaults. Default border colour, padding, and focus rings differ. A login form pixel-perfect on Chrome can ship 4 pixels taller on Firefox and break a card-based layout.

JavaScript differences worth knowing

The same patterns appear in JS:

  • new Date("2024-03-04") parsing. Older Safari treated this string as UTC; older Chrome treated it as local time. The same code shifts by hours depending on the engine. The fix is to always use explicit new Date(Date.UTC(...)).
  • Clipboard API. navigator.clipboard.writeText requires a user gesture in Safari and silently does nothing in some edge cases. Tests that "work locally" often fail on iOS only.
  • Intersection Observer thresholds. The exact pixel boundary at which isIntersecting flips can differ by a fraction across engines, breaking lazy-loading triggers that assume an exact threshold.

These are not bugs in your code — they are bugs in the assumption that all engines behave identically. Catching them is what cross-browser testing is for.

How to identify a browser-specific bug

When a tester spots strange behaviour on one browser, the diagnostic flow is short:

  1. Reproduce on at least one other engine. If the bug appears on all engines, it is a regular bug, not a cross-browser one. If it appears only on one, you are looking at a rendering or API difference.
  2. Check caniuse.com. Type the CSS property or JS API the feature uses. Look at when each engine added support and any known notes.
  3. Check the browser's developer console. Many cross-browser bugs throw a console error on the affected engine even when nothing visible breaks. The error itself often names the unsupported API.
  4. File the bug with engine, version, and OS in the title. "Date input does not show picker on Safari 16 macOS" is actionable. "Date picker broken" is not.

Testing strategy in practice

You do not test every CSS property on every engine. The pragmatic split most teams settle on:

  • Core functionality: test on every engine in the cross-browser policy. Sign-in, checkout, the primary user journey — these have to pass everywhere.
  • Visual checks: test the top three engines (Chrome, Safari, one other). Use side-by-side screenshots if the layout matters.
  • Long-tail engines: smoke-only, or relegate to user-reported bugs.

This buys most of the safety with a fraction of the effort.

⚠️ Common mistakes

  • Trusting "compiled and runs" on Chrome to mean "works everywhere." Modern build tools eliminate syntax errors but not behavioural differences. Engine-specific bugs survive the build pipeline silently.
  • Diagnosing without the dev console. Half of cross-browser bugs print a clear console error on the affected engine. Open the console first; do not guess.
  • Treating Safari iOS and Safari macOS as the same. Same engine, different operating system, different default behaviours, different viewport quirks. Test both.

🎯 Practice task

Spend 25 minutes building the cross-browser bug-catching reflex.

  1. Pick a feature on a real product that uses a date input, a file upload, or a custom select dropdown. Open it on Chrome, Safari (or iOS simulator), and Firefox.
  2. For each engine, take one screenshot of the same screen and compare them side by side. Note three differences — even if all three "work."
  3. For one of the differences, look up the underlying CSS property or JS API on caniuse.com. Write down which engines have full support, partial support, or no support.
  4. Pretend you have caught a real bug here. Draft a bug report title and one-paragraph description that names the engine, version, and the specific behaviour difference. Make it actionable enough that a developer could investigate without asking follow-up questions.

// tip to track lessons you complete and pick up where you left off across devices.