Create a bslib::bs_theme() styled with a Liquid Glass look: translucent
surfaces, backdrop blur, soft depth, and system typography. Pass the result
to theme = on fluidPage(), navbarPage(), bslib::page_sidebar(), or
any other page function that accepts a bslib theme.
Usage
glass_theme(
preset = c("light", "dark", "auto"),
primary = "#007AFF",
blur = 36,
saturation = 200,
radius = "1.5rem",
material = c("regular", "clear"),
plot_surface = c("clear", "opaque"),
intensity = 0.45,
tint = TRUE,
specular = TRUE,
nav_morph = TRUE,
ambient_motion = TRUE,
persist = FALSE,
scene = c("default", "tahoe", "dusk", "mesh", "aurora", "harbor", "grove"),
wallpaper = NULL,
flatten = FALSE,
tokens = NULL,
...
)Arguments
- preset
"light","dark", or"auto"."auto"followsprefers-color-schemeand updates when the OS theme changes.- primary
Accent color for buttons, links, and focus rings. Defaults to system blue (
#007AFF).- blur
Backdrop blur radius in pixels. Default
36matches the iOS 27 diffusion-first material.- saturation
Backdrop saturation percentage.
- radius
Default border radius for glass surfaces (CSS length). Prefer larger concentric radii (default
1.5rem).- material
"regular"(adaptive, most UI) or"clear"(more transparent; best over media-rich content with bold labels).- plot_surface
"clear"(default) keeps plot/table hosts translucent so wallpaper shows through."opaque"densifies.shiny-plot-output, plotly, gt, and DT hosts (~94% panel fill, readable ink) while leaving nav and controls on Liquid Glass. Also available as the CSS class.glass-plot-surface-opaqueon a host or ancestor.- intensity
Liquid Glass intensity from
0(Ultra Clear) to1(Tinted), matching iOS 27 Settings -> Appearance -> Liquid Glass. Default0.45. The web cannot read the OS slider; useglass_intensity_slider()for the in-app control.- tint
Content-aware ambient tint from plots/images (JS).
- specular
Pointer-driven specular highlight on glass surfaces (JS).
Compact navbar on scroll down; expand on scroll up (JS).
- ambient_motion
Animate the decorative ambient sheen. Set
FALSEto keep static glass surfaces. OS reduced-motion settings take priority.- persist
Remember preset, intensity, accent, material, plot surface, and scene in
localStoragefor this app path. DefaultFALSE(opt in).glass_page()turns this on.- scene
Wallpaper scene id from
glass_scenes()("default","tahoe","dusk","mesh","aurora","harbor","grove").- wallpaper
Optional image URL painted as a frosted photo behind the glass (https, data URI, or site-relative path). Photos are blurred and washed so body ink stays above the contrast floor (see
glass_css_tokens()).- flatten
TRUEstarts in print/export flatten mode (no backdrop blur). Seeglass_flatten().- tokens
Named list of public CSS token overrides (see
glass_css_tokens()/glass_add_tokens()).- ...
Additional arguments forwarded to
bslib::bs_theme().
Value
A bslib::bs_theme() object suitable for 'shiny' page functions.
Details
Light and dark surface tokens are compiled into dual CSS custom-property
packs. Switching preset at runtime (via update_glass_theme() or
preset = "auto") updates document.documentElement.dataset.glassPreset
without recompiling Sass or reloading the page. Accent color can also be
updated live with update_glass_theme() primary= (CSS variables).
Examples
theme <- glass_theme()
opaque <- glass_theme(
plot_surface = "opaque",
scene = "aurora",
tokens = list(blur = "28px")
)
if (interactive()) {
library(shiny)
ui <- fluidPage(
theme = glass_theme(preset = "auto"),
titlePanel("Liquid Glass"),
glass_theme_toggle(),
selectInput("color", "Color", c("Blue", "Purple", "Orange")),
plotOutput("plot")
)
server <- function(input, output, session) {
# Client onclick already switches; keep session in sync:
observe_glass_theme_toggle(input, session)
}
shinyApp(ui, server)
}