Building a Chrome extension that renders explanations next to your cursor sounds simple until the tooltip inherits the host page's CSS and breaks. Iframes avoid that — they're fully isolated — but iframe content can't match host-page fonts without a FOUC that makes the overlay feel foreign on every site you visit.
Shadow DOM solves this differently. The tooltip tree is scoped to the shadow root, so host stylesheets can't bleed in, but you can still read the host's computed font stack and apply it explicitly inside the shadow. The result looks native on any page without the layout-shift flash.
rabbitholes uses this to render explanations from Claude Haiku inline, next to wherever you've highlighted text. The shadow root mounts as a child of document.body, absolutely positioned to cursor coordinates. Because it doesn't touch the host DOM tree, it can't accidentally mutate classes, trigger reflows on adjacent elements, or conflict with the page's own event listeners.
The other thing iframes break is click propagation. If you want clicks inside the overlay to bubble to a handler in the extension's content script, you need a postMessage bridge — which means async round-trips for every interaction. Shadow DOM keeps everything synchronous in the same JS context, which matters here because rabbitholes lets you click any word inside an explanation to drill into it, or drag across multiple words to pick a phrase. That interactivity would have been substantially messier through an iframe.
The tradeoff: shadow DOM doesn't isolate JavaScript, only styles. Content scripts from other extensions can still reach into your shadow root if they know to look. For rabbitholes that's acceptable — there's no sensitive content in the tooltip, and the API key itself lives in chrome.storage.sync, never in the DOM.
One other note on the architecture: requests go directly from the browser to api.anthropic.com and api.search.brave.com. No intermediary server, zero telemetry. The key is stored in chrome.storage.sync and never serialized into page context.
Top comments (0)