The hard part of rabbitholes wasn't the API calls — it was making a tooltip that behaves correctly on pages I've never seen. Any extension that injects UI into arbitrary host pages has to answer: do you use an iframe or shadow DOM, and why?
I tried an iframe prototype first. The isolation is appealing: host CSS can't touch your UI, your JS runs in a separate context. But three things broke it for this use case.
First, fonts. An iframe starts with a blank stylesheet. To match the host page's type rendering, you'd need to detect the resolved font stack — not the specified one — which the browser doesn't expose directly. I didn't want tooltips that look visually foreign on every second site.
Second, positioning. rabbitholes places the tooltip next to the user's text cursor, using Range.getBoundingClientRect(). Those are viewport coordinates in the main document. Getting an iframe positioned correctly relative to a text selection means tracking the iframe's own offset and doing coordinate translation that breaks on scroll. Shadow DOM attaches a <div> to document.body directly, so selection coordinates map without conversion.
Third, the frame boundary adds latency and complexity to anything that needs to communicate with the content script — which is everything, since the extension logic lives there.
Shadow DOM in mode: 'closed' gives encapsulation for styles without a separate browsing context. The host page's cascade doesn't reach in; my tooltip's styles don't leak out. Font rendering inherits the host's context, so subpixel smoothing and system font fallbacks resolve correctly. The tooltip looks native.
The cost: JavaScript isn't isolated. Events bubble to the host. A few sites ate my Escape key via global keydown handlers until I added stopPropagation inside the shadow root.
The full tooltip tree — explanation from Claude Haiku 4.5, clickable words for deeper dives, follow-up input, Brave Search source chips — lives inside that shadow root. Requests go directly from the browser to api.anthropic.com and api.search.brave.com. No server in the middle, no telemetry.
Top comments (0)