Eight Mobile Safari Bugs That Break Shopify Themes
Most Shopify traffic is mobile and a large share of that is iOS Safari. These eight issues account for most of the "it looks broken on my iPhone" emails.
Why this is worth a dedicated pass
For most Shopify stores the majority of sessions are mobile, and a large share of those are iOS Safari. That makes it the highest-traffic rendering engine on the store and the one least likely to be sitting on the developer's desk.
The unifying property of everything below: it's all valid CSS. No linter complains, no console error appears, no build step fails. Safari simply ignores a property, or interprets it differently, and the page renders wrong without telling anyone.
The four CSS issues
1. backdrop-filter without the prefix
Frosted-glass headers are everywhere in modern Shopify themes. Safari still wants -webkit-backdrop-filter. Without it the blur simply doesn't happen β and because these headers are usually semi-transparent, the result is page content scrolling visibly through the navigation.
.site-header {
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
background: rgba(255, 255, 255, 0.72);
}
2. gap on flex containers, older iOS
Flexbox gap arrived late in Safari. On older iOS versions it's ignored on flex containers, so a product grid built with display: flex; gap: 16px renders with every card flush against its neighbour.
It works on grid in more versions than flex, which is why one grid on the page looks fine and another doesn't β a genuinely confusing symptom.
.product-grid > * { margin: 0 8px 16px; }
@supports (gap: 1rem) {
.product-grid { gap: 16px; }
.product-grid > * { margin: 0; }
}
3. position: sticky quirks
Older Safari needs -webkit-sticky. Beyond the prefix, sticky silently does nothing if any ancestor has overflow: hidden β true in every engine, but Safari is where you notice, because sticky headers and sticky add-to-cart bars are mobile patterns.
.sticky-atc {
position: -webkit-sticky;
position: sticky;
bottom: 0;
}
/* An ancestor with overflow:hidden will kill this silently. */
4. clip-path without the prefix
Angled section dividers and shaped image masks need -webkit-clip-path. Without it Safari renders the unclipped element β usually a rectangle where a diagonal should be, often overlapping the section below.
-webkit- partner catches all of them before a browser is involved.
The four behavioural issues
5. 100vh and the address bar
The classic. iOS Safari treats 100vh as the viewport height with browser chrome hidden, so a full-height hero is taller than the visible area. Your CTA sits under the address bar, and on a product hero that's the buy button.
.hero {
height: 100vh; /* fallback for older browsers */
height: 100dvh; /* actual visible viewport */
}
Also worth knowing: dvh changes as the address bar collapses on scroll, so anything animating against it can jitter. For sticky elements, svh (smallest viewport height) is often the steadier choice.
6. Autoplay video that doesnβt
Video heroes are common and iOS blocks autoplay unless conditions are met. Miss one attribute and the client sees a black rectangle or a still frame where you designed motion.
<video autoplay muted loop playsinline poster="hero.jpg">
<source src="hero.mp4" type="video/mp4">
</video>
playsinline is the one people forget β without it iOS may take the video fullscreen. And muted is non-negotiable: audio means no autoplay, full stop. Always set a poster so the fallback is a designed frame rather than black.
7. Form controls Safari restyles
iOS applies its own appearance to selects, date and number inputs, and search fields β rounded corners, inner shadows, its own arrows. Your carefully styled variant selector looks like a system control.
.variant-select {
-webkit-appearance: none;
appearance: none;
border-radius: 8px;
background-image: url("data:image/svg+xml,..."); /* your own arrow */
}
Related and worth setting once: font size below 16px on an input causes iOS to zoom the whole page on focus. On a checkout or search field that feels like a bug to the user.
8. Scroll behaviour and overscroll
Momentum scrolling, overscroll bounce and scroll-behavior: smooth all behave differently in Safari. Scroll-linked effects β parallax sections, headers that transform on scroll β are where this shows up, often as jitter rather than an outright break.
Also: a modal that doesn't lock body scroll will let the page behind it scroll on iOS even when it doesn't elsewhere. Use overscroll-behavior: contain on scrollable overlays.
Testing this without a drawer full of iPhones
You need two layers, because they catch different things.
The practical split: run WebKit captures on every build, because it's free and catches the prefix and layout class. Reserve real-device checks for pre-launch on the two or three templates that carry the revenue β home, product, cart.
A pass that takes ten minutes
- Scan the CSS for standard properties missing their
-webkit-partner. Catches issues 1, 3 and 4 with no browser. - Capture in WebKit at phone width. Catches 2 and most of 1, 3, 4 visually.
- Grep for
100vhand confirm each has advhorsvhcompanion. - Check every
<video>for all four autoplay attributes plus a poster. - On a real iPhone: scroll the homepage top to bottom, add to cart, open the cart drawer. That's where 5, 6 and 8 surface.
How ThemeSync covers this
- WebKit is a first-class capture engine. Screenshots run through Chromium, Firefox and WebKit, so Safari rendering is part of the normal pass rather than a special exercise.
- A code scan flags the prefix issues directly. Static rules check for
backdrop-filterwithout-webkit-backdrop-filter, flexgapagainst older Safari,position: stickywithout-webkit-sticky,clip-pathandappearancewithout prefixes, and::placeholdergaps β each with severity, file and line. - Phone, tablet and desktop presets are built in. Captures run at iPhone, iPad, Android and desktop sizes at the right pixel ratios, so small-viewport failures are visible.
- Real Safari on real devices is available for the last mile. When you need genuine iOS behaviour on the revenue templates, that runs against real hardware rather than an emulation.
- Overlays can be dismissed before capture. Auto-close cookie banners and popups to get clean screenshots, or leave them to see what the customer actually meets.
Takeaways
- All eight of these are valid CSS. Nothing errors β Safari just ignores or reinterprets it.
- Prefix
backdrop-filter,clip-path,position: stickyandappearance, and always ship a fallback for the blur. - Feature-detect flex
gapwith@supportsrather than assuming support. - Never use bare
100vhfor a full-height hero. Usedvh, orsvhfor sticky elements. - Autoplay video needs
autoplay muted loop playsinlineand a poster.playsinlineis the one that gets missed. - Reset
-webkit-appearanceon form controls, and keep input font size at 16px or above to stop focus zoom. - WebKit captures catch most of it cheaply; save real-device checks for home, product and cart.
- Test at 390px with the overlays on. That's where it actually breaks.
Catch Safari bugs before your clientβs iPhone does
ThemeSync captures every template in Chromium, Firefox and WebKit across phone, tablet and desktop, and statically flags missing vendor prefixes with file and line.
Try ThemeSync Free →