ImpulseyeImpulseye
FeaturesIntegrationsPricingBlogChangelogIs It Down?
All posts
Engineering

The one CSS property that broke my navbar, only on iPhone

Three fix attempts, two of them wrong, before I found the actual culprit: a property that behaves completely differently on iOS Safari than everywhere else I tested it.

June 26, 2026 5 min read

A user sent me a screen recording of my own changelog page looking subtly, infuriatingly broken — a sliver of content peeking out above the navbar, like the page had loaded scrolled slightly past the top. Only on their iPhone. Never on my desktop, my Android phone, or any emulator I threw at it.

This is the story of three attempts to fix it, two of which made things worse, and the one line of CSS actually responsible.

Attempt 1: Safe area

iPhones with a notch or Dynamic Island reserve space at the top of the screen, and CSS has an env variable for exactly this: env(safe-area-inset-top). A sliver of misplaced content near the top of the screen, on iPhone specifically — this felt like a textbook safe-area problem. I added viewport-fit=cover to the viewport meta tag and padded the nav with the safe-area inset.

What actually happened

The nav didn't just get padding — it lost most of its usable height. Suddenly I could only see about half the navbar unless I scrolled and held at the very top, and it would bounce back a moment later. I'd fixed nothing and broken something else.

viewport-fit=cover changes how the whole page's height is calculated relative to the viewport, and my layout leaned on h-screen in a few places. Changing the viewport contract out from under a fixed-height layout is asking for exactly this kind of collapse. Reverted both changes.

Attempt 2: Hide the seam

Next theory: maybe the nav background just wasn't opaque enough to cover whatever was bleeding through underneath it, and the "gap" was really page content showing through a translucent nav.

tsx
// Before
className="bg-slate-950/70 supports-[backdrop-filter]:bg-slate-950/55"

// Attempt two
className="bg-slate-950 supports-[backdrop-filter]:bg-slate-950/80"

This made the nav look a little cleaner, but the actual bug — the page loading scrolled slightly past the top — was still there. I'd papered over a symptom without finding the cause. Worth keeping the opacity change for its own sake, but it wasn't the fix.

Two wrong attempts in, the only reliable move left was to stop theorizing about what iOS does and go find out what iOS actually does with this specific page.
- The moment I stopped guessing

Root cause

The page had one detail every other page on the site didn't: a wrapper div using overflow-x-clip around an animated, horizontally-sliding detail panel. The intent was narrow — clip horizontal overflow during the slide-in animation, leave vertical scrolling alone.

iOS Safari doesn't see it that way. On iOS Safari specifically, overflow-x: clip can corrupt the scroll-container geometry for the whole element, affecting both axes rather than just the one you named. The practical result was a page that loaded already scrolled slightly past its actual top — precisely the sliver-of-content-above-the-nav symptom from the very first screen recording.

tsx
// The wrapper that caused it
<div className="overflow-x-clip">
  <TimelinePanel />
</div>

// The fix: remove it. The animated panel inside already has
// overflow-hidden of its own, which is enough to contain the slide.
<TimelinePanel />

While I was in there, I also found a second, unrelated iOS quirk on the same page: a flex-col-reverse layout (used so the timeline rendered in a particular visual order) interacting badly with iOS Safari's scroll-anchoring, which was independently causing the page to sometimes load scrolled to the bottom instead of the top. Switched it to a plain flex-col with an md:order-first instead, which achieves the same visual order without touching scroll direction at all.

Lesson

Two real bugs, both invisible outside iOS Safari, both hiding behind CSS properties that do exactly what you'd expect everywhere except the one browser engine that matters most for mobile traffic. My first two attempts treated the symptom (visual gap, translucent background) instead of the mechanism (corrupted scroll geometry) — which is the natural trap when a bug only reproduces on hardware you're not holding.

The actual lesson wasn't about CSS specifics — it's that "this only happens on iOS" is a hypothesis about the platform, not an excuse to guess at UI-level fixes. Once I treated it as a real platform quirk worth researching instead of a look I could paper over, it took one search and one wrapper removal to fix two separate bugs at once.

Back to all posts
Share

Monitor your sites with Impulseye

Uptime checks, SSL warnings, and alerts across 9 channels.

Start free

Keep reading

Engineering 5 min

I built myself a tiny ops dashboard. It found 30 real problems in five minutes.

A personal, owner-only page to stop bouncing between the Hetzner, Supabase, and Resend consoles by hand — and it immediately surfaced a stack of real database performance issues I didn't know I had.

July 19, 2026Read
Infrastructure 7 min

My load test was lying to me, and I almost believed it

Before renting a real server, I built a load-testing rig to find Impulseye's actual ceiling. It reported a ceiling that didn't exist — the test harness itself had two bugs, and both of them looked exactly like a capacity problem.

July 14, 2026Read
Postmortem 6 min

The signup bug that almost shipped on launch day

A single trigger wired to the wrong table meant every new signup would have failed — and every digest email would have silently gone nowhere. Here's how I found it before opening the doors.

July 2, 2026Read
ImpulseyeImpulseye

Uptime monitoring that is dead simple. Instant alerts via email, Slack, and Discord, set up in under 30 seconds.

support@impulseye.com

Product

  • Features
  • Integrations
  • Pricing
  • Blog
  • Changelog

Tools

  • Is It Down?
  • Dashboard
  • Status Pages
  • Impulseye Status
  • API Docs
  • FAQ

Legal

  • Terms of Service
  • Privacy Policy
  • Refund Policy

© 2026 Impulseye. All rights reserved.

ContactTermsPrivacy