Theming
Inherit the portal's colors, light/dark mode, and visible viewport automatically.
A portal block should look like it belongs in the portal that hosts it. The SDK
makes that automatic: the portal's theme is delivered across the bridge and
applied to your document, then kept in sync as the user switches themes, with no work
required beyond initialize().
How it works
The portal can't reach into a cross-origin iframe to style it, so it sends theme
data through the bridge as a string of CSS custom properties. During
initialize() the SDK:
- Injects the portal's
cssVariablesinto a<style id="spark-portal-theme">in your<head>. - Applies the
light/darkclass to<html>. - Subscribes to
theme-updateandviewport-updatemessages so later changes apply live and the cached session stays current.
If you build with the Spark UI component library, those CSS variables are exactly what the components read, so inheriting the portal theme is fully automatic. Most blocks never need the functions below.
Manual theme control
For advanced cases (custom theming, testing, blocks that opt out of the automatic flow) the underlying utilities are exported.
injectCSSVariables(css)
Injects (or replaces) the portal theme <style> element. Returns true on
success, false if the CSS string was empty or injection failed.
import { injectCSSVariables } from '@epilot/spark-sdk'
injectCSSVariables(':root { --spark-9: #005eb4; }')removeCSSVariables()
Removes the injected theme <style> element.
setThemeClass(theme)
Sets the light/dark class on <html>, removing the opposite one.
import { setThemeClass } from '@epilot/spark-sdk'
setThemeClass('dark')removeThemeClass()
Removes both light and dark classes from <html>.
Viewport variables
The SDK also reflects the portion of your iframe currently visible in the parent
viewport onto :root as CSS variables. This lets you pin or center UI relative to
what the user can actually see, which is useful for sticky bars and floating actions in a
tall, scrolled-past iframe. These update automatically while the user scrolls the
portal.
| CSS variable | Meaning (iframe-local pixels) |
|---|---|
--spark-viewport-top | Top of the visible region. |
--spark-viewport-height | Height of the visible region. |
--spark-viewport-center-y | Vertical center of the visible region. |
--spark-viewport-bottom-offset | Distance from content bottom to visible edge. |
/* Center a floating element in whatever part of the block is on screen */
.floating-action {
position: absolute;
top: var(--spark-viewport-center-y, 50%);
transform: translateY(-50%);
}