A client site started showing something odd on iPhone: scroll past a sticky sidebar or a sticky filter bar, and the address bar and bottom toolbar pick up its background color. Scroll further, past the element entirely, and the tint stays. Not a flicker. A stuck cache.
This isn’t an Apple bug. Position:sticky and position:fixed are exactly as compliant as they’ve always been. Safari 26’s Liquid Glass redesign just reads them for something nobody designed sticky elements for: coloring the browser’s own native chrome. Theme-color won’t get you out of it, and neither will filing a bug report.
The wrong theories
The forums are full of guesses: the toolbar is just collapsing and expanding on scroll like it always has, it’s layout jank from a heavy page, it’s a viewport-fit problem. We chased all three on a real project before finding the actual cause, so save yourself the time.
viewport-fit=cover and safe-area padding are worth having regardless (notches, home indicators), but they do nothing for this. Layout performance matters, but a perfectly smooth 60fps page still gets tinted. And the theme-color meta tag, the thing every guide from the last eight years tells you to set for exactly this kind of browser-chrome-color problem, is flatly ignored:
“Safari 26 no longer reads theme-color. It reads your CSS, and it’s pickier than you’d expect.”
That’s from Pavel Larionov’s writeup at 1ar.io, which is the clearest account of this we found and matches what we confirmed independently on-device.
What’s actually happening
Safari 26 scans the page for position: fixed or position: sticky elements sitting at a viewport edge and reads two properties directly off them, both completely ordinary CSS:
“Safari 26 scans for position: fixed or position: sticky elements near the viewport edges and reads two properties: background-color on the element itself [and] backdrop-filter on the element itself.”
Nothing about that is non-compliant. background-color and backdrop-filter on a sticky or fixed element do exactly what the spec says they do. What changed is that Safari’s native chrome now reads them for something new: matching its own UI to whatever’s stuck at the edge. If your sticky sidebar has a light card background and your header is dark, Safari will happily paint the toolbar to match whichever one is currently stuck there. Deliberate, confirmed by Apple, not an oversight:
“The general fixed-element tinting behavior appears to be by design rather than a bug. It’s how Liquid Glass is supposed to work.”
(Developers filed this as WebKit Bug #302272, duplicate of #300965, expecting the old behavior back. Safari 26.2 fixed a related fullscreen-dialog issue but left the core tinting behavior untouched, because it isn’t a defect to fix.)
What we found on-device, testing this directly rather than trusting either theory: a solid-background sticky element gets its color inherited by both bars independently. Make it transparent, and the bars fall back to Apple’s own default fill instead of showing the page’s actual background color underneath, so it’s not sampling rendered pixels, it’s reading the element’s own computed background-color. And the element has to touch each edge separately: getting stuck at the top colors the top bar, scrolling it down to touch the bottom colors the bottom bar, and once both have been touched, both stay that color regardless of what scrolls past afterward.
The trick that doesn’t hold up
The obvious fix, and the one the 1ar.io piece itself recommends, is to keep the fixed/sticky element’s own background transparent and move the actual paint onto a plain position: absolute child inside it:
.sticky-header {
position: sticky;
top: 0;
background: transparent; /* Safari reads this as "nothing to tint" */
}
.sticky-header__bg {
position: absolute;
inset: 0;
background: #fff;
backdrop-filter: blur(12px);
z-index: -1;
}
Clean idea. Safari only reads the sticky/fixed element’s own declared background, so a descendant carrying the paint should be invisible to the sampler.
We built it, and it did not change anything on the actual device. Same tint, same stuck-cache behavior, transparent parent or not. Worth knowing before you spend an afternoon restructuring every sticky component on a site for a fix that reads correctly on paper but didn’t hold up in testing.
The fix that actually works
Don’t let anything stay stuck at the edge. Drop position: sticky (or fixed, where it’s not load-bearing) below whatever breakpoint your layout collapses to single-column on mobile:
.sidebar {
position: sticky;
top: 2rem;
}
@media (max-width: 899px) {
.sidebar {
position: relative; /* not static, see below */
top: 0; /* the sticky-offset top still applies under relative */
}
}
Two things that’ll bite you if you skip them:
position: relative, not static. If the element has any absolutely-positioned descendant (an icon, a decorative pseudo-element), static drops the containing block and that descendant falls back to the document root, landing wherever, usually the top of the page. relative with no offset behaves identically to static for layout purposes but keeps the containing block local.
Reset top explicitly. If the sticky version had a top value for its scroll-offset (top: calc(2rem + var(--header-height)), say), that value doesn’t disappear when you switch to relative, relative still honors top. Left unset, it’ll shift the element down by however many rem that was, without closing the gap it left behind. Looks like a layout bug, is actually a leftover sticky offset.
What this costs you
You lose the follow-scroll behavior. For a sidebar or a table-of-contents nav, that’s a minor UX downgrade, worth it. For something whose entire purpose is staying visible, a persistent “book a call” bar, a mobile checkout CTA, it’s a real trade-off. We kept one of those sticky on a recent project and accepted the tint, because losing the always-visible CTA cost more than a mismatched toolbar color. Decide per element, not site-wide.
Bottom line
theme-color is dead for this purpose, not because Apple broke it, because Apple replaced it with something CSS-native. The absolute-child workaround sounds right and isn’t confirmed to work. The only fix we could get to hold on-device is removing the sticky/fixed positioning at the edge entirely, scoped to wherever your layout is single-column.
None of this is a compatibility bug to wait out. CSS evolves, browser chrome now reads more of it than it used to, and the sites that adapt their sticky positioning will look intentional. The ones that don’t will look broken, through no fault of the spec. Test on an actual iPhone before you ship whatever you land on. Chrome’s devtools and simulators won’t show you any of this.