关于 shiny-bslib-theming
shiny-bslib-theming 是使用 bslib 和 Bootstrap 5 为 Shiny 应用设置样式的技能指南,涵盖主题预设、自定义 Sass 与字体、色彩模式、绘图主题及交互式预览工具。
主要功能
- 01Shiny 与 Bootswatch 主题预设
- 02自定义颜色、字体和 Sass
- 03从 _brand.yml 应用品牌设置
- 04浅色与深色色彩模式
- 05使用 thematic 设置 R 绘图主题
- 06交互式主题预览
适用场景
- 01为 Shiny 应用应用视觉主题
- 02让绘图匹配应用的颜色和字体
- 03开发时预览并调整主题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posit-dev/ skills --skill shiny-bslib-theming安装后在 Claude Code 中输入/shiny-bslib-theming确认已加载。
附带文件references/dark-mode.mdreferences/sass-and-css-variables.md
详细介绍
使用 bslib 设置 Shiny 应用主题
使用 bslib 的 Bootstrap 5 主题系统自定义 Shiny 应用的外观。从快速应用 Bootswatch 主题,到高级 Sass 自定义和动态切换色彩模式。
快速入门
“shiny”预设(推荐作为起点):
page_sidebar(
theme = bs_theme(), # "shiny" preset by default — polished, not plain Bootstrap
...
)
Bootswatch 主题(用于采用不同的视觉风格):
page_sidebar(
theme = bs_theme(preset = "zephyr"), # or "cosmo", "minty", "darkly", etc.
...
)
自定义颜色和字体:
page_sidebar(
theme = bs_theme(
version = 5,
bg = "#FFFFFF",
fg = "#333333",
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat")
),
...
)
从 _brand.yml 自动应用品牌设置:
如果应用或项目目录中存在 _brand.yml 文件,bs_theme() 会自动发现并应用它。无需更改代码。需要 brand.yml R 包。
bs_theme(brand = FALSE) # Disable auto-discovery
bs_theme(brand = TRUE) # Require _brand.yml (error if not found)
bs_theme(brand = "path/to/brand.yml") # Explicit path
主题设置工作流
- 从
"shiny"预设(默认)或与预期外观接近的 Bootswatch 主题开始 - 自定义主要颜色(
bg、fg、primary) - 使用
font_google()或其他字体辅助函数调整字体 - 通过
...或bs_add_variables()微调 Bootstrap Sass 变量 - 如有需要,使用
bs_add_rules()添加自定义 Sass 规则 - 启用
thematic::thematic_shiny(),让图表与主题保持一致 - 开发期间使用
bs_themer()进行交互式预览
示例:
theme <- bs_theme(preset = "minty") |>
bs_theme_update(
primary = "#1a9a7f",
base_font = font_google("Lato")
) |>
bs_add_rules("
.card { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
")
bs_theme()
用于创建 Bootstrap 主题的核心函数。返回 sass::sass_bundle() 对象。
bs_theme(
version = version_default(),
preset = NULL, # "shiny" (default for BS5+), "bootstrap", or Bootswatch name
..., # Bootstrap Sass variable overrides
brand = NULL, # brand.yml: NULL (auto), TRUE (require), FALSE (disable), or path
bg = NULL, fg = NULL,
primary = NULL, secondary = NULL,
success = NULL, info = NULL, warning = NULL, danger = NULL,
base_font = NULL, code_font = NULL, heading_font = NULL,
font_scale = NULL, # Scalar multiplier for base font size (e.g., 1.5 = 150%)
bootswatch = NULL # Alias for preset
)
使用 bs_theme_update(theme, ...) 修改现有主题。使用 is_bs_theme(x) 检查对象是否为主题。
预设和 Bootswatch
“shiny”预设(推荐): 对于 Bootstrap 5 及更高版本,bs_theme() 默认使用 preset = "shiny"。这是一个精心打磨、专为 Shiny 应用设计的主题,并非原生 Bootstrap。它为卡片、侧边栏、数值框和其他 bslib 组件提供专业样式和精心挑选的默认设置。从此处开始,先自定义颜色和字体,再考虑使用 Bootswatch 主题。
原生 Bootstrap: 使用 preset = "bootstrap" 可移除“shiny”预设,采用未经修改的 Bootstrap 5 样式。
内置预设: builtin_themes() 会列出 bslib 自带的预设。
Bootswatch 主题: bootswatch_themes() 会列出所有可用的 Bootswatch 主题。选择适合应用用途和目标受众的主题——不要默认应用某个主题。
常用选项:"zephyr"(明亮、现代)、"cosmo"(简洁)、"minty"(清新绿)、"flatly"(扁平设计)、"litera"(清晰)、"darkly"(深色)、"cyborg"(深色)、"simplex"(极简)、"sketchy"(手绘风格)。
主要颜色
影响最大的颜色——更改这些颜色会通过变量级联影响 数百条 CSS 规则:
| 参数 | 说明 |
|---|---|
bg | 背景颜色 |
fg | 前景(文本)颜色 |
primary | 品牌主色(链接、导航激活状态、输入焦点) |
secondary | 操作按钮的默认颜色 |
success | 正向/成功状态(通常为绿色) |
info | 信息内容(通常为蓝绿色) |
warning | 警告(通常为黄色) |
danger | 错误/破坏性操作(通常为红色) |
bs_theme(
bg = "#202123", fg = "#B8BCC2",
primary = "#EA80FC", secondary = "#48DAC6"
)
颜色提示:
bg/fg:色相相近、亮度差异较大(确保对比度,便于阅读)primary:与bg和fg都形成对比;用于超链接、导航和输入焦点- 颜色可以使用
htmltools::parseCssColors()支持的任何格式
字体排版
三个字体参数:base_font、heading_font、code_font。使用 font_scale 统一缩放所有字号(例如,1.5 表示 150%)。
每个参数都接受单个字体、font_collection() 或字体名称字符向量。
font_google()
在本地下载并缓存 Google Fonts(默认 local = TRUE)。仅首次下载时需要联网。
bs_theme(
base_font = font_google("Roboto"),
heading_font = font_google("Montserrat"),
code_font = font_google("Fira Code")
)
使用可变字重:font_google("Crimson Pro", wght = "200..900")
使用指定字重:font_google("Raleway", wght = c(300, 400, 700))
建议设置备用字体,避免网络较慢时出现不可见文本闪烁(FOIT):
bs_theme(
base_font = font_collection(
font_google("Lato", local = FALSE),
"Helvetica Neue", "Arial", "sans-serif"
)
)
字体搭配参考网站:fontpair.co
font_link()
用于自定义字体 URL 的 CSS Web 字体接口:
font_link("Crimson Pro",
href = "https://fonts.googleapis.com/css2?family=Crimson+Pro:[email protected]")
font_face()
对于需要完整控制 @font-face 的本地托管字体文件:
font_face(
family = "Crimson Pro",
style = "normal",
weight = "200 900",
src = "url(fonts/crimson-pro.woff2) format('woff2')"
)
font_collection()
按回退顺序组合多种字体:
font_collection(font_google("Lato"), "Helvetica Neue", "Arial", "sans-serif")
低级主题函数
用于自定义 bs_theme() 命名参数之外的内容。这些函数直接作用于 Bootstrap 的 Sass 层。
bs_add_variables()
添加或覆盖 Bootstrap Sass 变量默认值:
theme <- bs_add_variables(
bs_theme(preset = "sketchy", primary = "orange"),
"body-bg" = "#EEEEEE",
"font-family-base" = "monospace",
"font-size-base" = "1.4rem",
"btn-padding-y" = ".16rem"
)
.where 参数控制在 Sass 编译顺序中的位置:
.where | 使用场景 |
|---|---|
"defaults"(默认) | 使用 !default 标志设置变量默认值。放在 Bootstrap 自身默认值之前。 |
"declarations" | 引用其他 Bootstrap 变量(例如 $secondary)。放在 Bootstrap 默认值之后。 |
"rules" | 放在所有规则之后。较少需要。 |
引用 Bootstrap 变量:
# This fails in bs_theme() because $secondary isn't defined yet:
# bs_theme("progress-bar-bg" = "$secondary")
# Use bs_add_variables with .where = "declarations" instead:
bs_theme() |>
bs_add_variables("progress-bar-bg" = "$secondary", .where = "declarations")
bs_add_rules()
添加可引用 Bootstrap 变量和混入的自定义 Sass/CSS 规则:
theme <- bs_theme(primary = "#007bff") |>
bs_add_rules("
.custom-card {
background: mix($bg, $primary, 95%);
border: 1px solid $primary;
padding: $spacer;
@include media-breakpoint-up(md) {
padding: $spacer * 2;
}
}
")
从外部文件加载:bs_add_rules(sass::sass_file("www/custom.scss"))
可用的 Sass 函数:lighten()、darken()、mix()、rgba()、color-contrast()。
可用的 Bootstrap 混入:@include media-breakpoint-up()、@include box-shadow()、@include border-radius()。
bs_add_functions() 和 bs_add_mixins()
向主题包添加自定义 Sass 函数或混入:
theme |>
bs_add_functions("@function my-tint($color) { @return mix(white, $color, 20%); }") |>
bs_add_rules(".highlight { background: my-tint($primary); }")
bs_bundle()
将 sass::sass_bundle() 对象追加到主题中(用于打包可复用的主题扩展):
my_extension <- sass::sass_layer(
defaults = list("my-var" = "red !default"),
rules = ".my-class { color: $my-var; }"
)
theme <- bs_theme() |> bs_bundle(my_extension)
Bootstrap Sass 变量
通过 bs_theme(...) 或 bs_add_variables() 传入任意 Bootstrap 5 Sass 变量。
查找变量名称: https://rstudio.github.io/bslib/articles/bs5-variables/
常用变量:
bs_theme(
"border-radius" = "0.5rem",
"card-border-radius" = "1rem",
"card-bg" = "lighten($bg, 5%)",
"navbar-bg" = "$primary",
"link-color" = "$primary",
"font-size-base" = "1rem",
"spacer" = "1rem",
"btn-padding-y" = ".5rem",
"btn-padding-x" = "1rem",
"input-border-color" = "#dee2e6"
)
值可以是引用变量、函数和数学运算的 Sass 表达式。
Bootstrap CSS 自定义属性
有关以下内容的详细信息,请参阅 sass-and-css-variables.md:
- Sass 变量如何编译为
--bs-*CSS 自定义属性 - 运行时与编译时变量层
- Bootstrap 5.3 颜色模式如何使用 CSS 变量覆盖
- 使用
data-bs-theme按元素设置主题 - 用于一次性样式设置的 CSS 工具类
深色模式和颜色模式
有关以下内容的详细信息,请参阅 dark-mode.md:
- Bootstrap 5.3 的客户端颜色模式系统(
data-bs-theme属性) - 用于用户控制切换的
input_dark_mode()和toggle_dark_mode() - 使用
session$setCurrentTheme()在服务器端切换主题 - 编写适用于浅色/深色模式的自定义 Sass
- 组件兼容性(哪些组件会响应主题设置,哪些不会)
为 R 绘图设置主题
bs_theme() 只影响 CSS。R 绘图输出(在服务器端渲染为图像)不会自动匹配主题。请使用 thematic 包:
library(thematic)
thematic_shiny(font = "auto") # Call before shinyApp()
shinyApp(ui, server)
- 适用于 base R、ggplot2 和 lattice
- 将 CSS 颜色转换为 R 绘图默认值
font = "auto"也会匹配bs_theme()中的字体- 可与
bs_themer()配合,实现实时预览
设置全局 ggplot2 主题,以进一步保持一致性:
library(ggplot2)
theme_set(theme_minimal())
仪表板背景样式
bslib-page-dashboard CSS 类会在主内容区域后方添加浅灰色背景,让卡片在背景衬托下更加醒目,使仪表板风格的应用呈现更精致的外观。这属于主题样式细节——不会改变布局行为,只会影响视觉效果。
对于 page_sidebar() 仪表板:
page_sidebar(
class = "bslib-page-dashboard",
title = "My Dashboard",
sidebar = sidebar(...),
...
)
对于包含仪表板页面的 page_navbar():
将此类应用于单独的 nav_panel() 容器(而不是 page_navbar() 本身),这样只有面向仪表板的页面才会显示灰色背景:
page_navbar(
title = "Analytics",
nav_panel("Dashboard", class = "bslib-page-dashboard",
layout_column_wrap(...)
),
nav_panel("Report",
# No dashboard class — standard white background for prose/reports
...
)
)
交互式主题工具
bs_theme_preview()
独立演示应用,可预览包含多个示例 UI 组件的主题:
bslib::bs_theme_preview() # Default theme
bslib::bs_theme_preview(bs_theme(preset = "darkly")) # Custom theme
默认包含主题设置 UI(with_themer = TRUE)。
run_with_themer()
使用主题编辑器覆盖层运行现有 Shiny 应用(而不是调用 shiny::runApp()):
run_with_themer(shinyApp(ui, server))
run_with_themer("path/to/app")
bs_themer()
将主题编辑器添加到你自己的应用的服务器函数中:
server <- function(input, output, session) {
bs_themer() # Add during development, remove for production
# ...
}
这三个工具都会将生成的 bs_theme() 代码打印到 R 控制台,方便复制粘贴。**限制:**仅支持 Bootstrap 5 及更高版本、Shiny 应用和 runtime: shiny R Markdown;不会影响未使用 bs_dependency_defer() 的第三方小部件。
主题检查
获取计算后的 Sass 变量值:
vars <- c("body-bg", "body-color", "primary", "border-radius")
bs_get_variables(bs_theme(), varnames = vars)
bs_get_variables(bs_theme(preset = "darkly"), varnames = vars)
检查对比度(用于无障碍访问):
bs_get_contrast(bs_theme(), c("primary", "dark", "light"))
尽量符合 WCAG AA 标准:普通文本的对比度为 4.5:1,大号文本为 3:1。
最佳实践
- 优先使用
bs_theme(),而非自定义 CSS —— 变量会自动级联到所有相关组件 - 固定 Bootstrap 版本:
bs_theme(version = 5)可避免默认值变更导致的问题 - 使用
font_collection()设置备用字体,避免网络连接缓慢时出现 FOIT - 跨组件测试:输入框、按钮、卡片、导航栏、图表、表格、模态框、Toast 和移动端
- 使用
bs_get_contrast()和浏览器开发者工具检查无障碍访问 - 对于一次性样式,使用 CSS 工具类,而非自定义 CSS(参见 sass-and-css-variables.md)
- 将复杂主题整理到单独的
theme.R文件中:
# theme.R
app_theme <- function() {
bs_theme(
version = 5,
primary = "#2c3e50",
base_font = font_google("Lato"),
heading_font = font_google("Montserrat", wght = c(400, 700))
) |>
bs_add_rules(sass::sass_file("www/custom.scss"))
}
参考文件
- sass-and-css-variables.md —— Bootstrap 的双层变量系统、CSS 自定义属性、工具类
- dark-mode.md —— 颜色模式、深色模式、动态主题设置、组件兼容性