Open Source · MIT · Safari family

bleedblend

**Zero-config Safari chrome tinting — across iPhone, iPad, and Mac.**

One import paints the Safari status bar and URL bar to match your page content at every viewport edge — gradients, opaque sections, and rubber-band overscroll, all handled automatically. No theme-color juggling, no tint config. bleedblend tames Safari's native tinting rather than painting its own — and Safari 26's Liquid Glass spans that tinting across iPhone, iPad, and Mac, so the same page structure stays predictable across the whole Safari family: iOS gets its quirks actively wrangled, Mac just works because the model is now unified.

How it works

1.

The problem

Safari 26 derives its chrome tint — the status bar and URL bar — from whatever sits at the viewport edge, the same model across iPhone, iPad, and Mac. But the rules are quirky, undocumented, and shift between versions — and on iPhone and iPad they bite hardest: gradients leave a visible seam, the compact tab bar shifts the tint by ~30px, rubber-band overscroll exposes the wrong background color, and `theme-color` is simply ignored on iOS 26.

2.

The solution

Add `import 'bleedblend/auto'` once. bleedblend watches scroll, resize, and visualViewport events and, per viewport edge, decides whether to step back and let Safari sample naturally or render a small tint in exactly the right color — reading gradient stops straight from your page, no hand-tuned arrays.

3.

The result

The status bar and URL bar stay perfectly in sync with the page: gradient interpolation continues into the chrome, the footer color engages at page end, and iOS rubber-band overscroll is painted the same color instead of leaking your fallback background.

What's inside

Zero-config auto-detect

`import 'bleedblend/auto'` is the entire API. It reads gradient stops from your `body::before`, `body`, or `<html>` and computes the right chrome color at each edge — no stop arrays to maintain.

Edge-aware state machine

Per viewport edge it picks one of three states — defer to a sticky header you own, step back when Safari's native sampling is already right, or tint only when the edge would otherwise be the wrong color.

Overscroll & gradient handling

Extends your gradient into the chrome and overrides `<html>`, `<body>`, and `body::before` together so iOS rubber-band overscroll tints the same color — no background leak at page end.

Framework-agnostic + Tailwind

Works from any framework via one import, with an `onPageLoad` hook for SPA page transitions. Ships a Tailwind plugin plus `.bleedblend-top` / `.bleedblend-bottom` — the recipe that makes your own sticky header or footer tint the chrome on purpose, across the whole Safari family.

Setup

Install `bleedblend` from npm (or copy the source in), set your viewport meta to `viewport-fit=cover`, and add `import 'bleedblend/auto'` to your entry point. That one line is the whole setup. Need a custom section selector or a page-transition hook? Reach for `createBleedblendAuto()` from `bleedblend/utils`.