+ - 0:00:00
Notes for current slide
Notes for next slide

Styling Shiny & R Markdown with {bslib} & {thematic}

Carson Sievert, Software Engineer @ RStudio

Slides: https://bit.ly/r-pharma2020

@cpsievert

@cpsievert

cpsievert.me

cpsievert1@gmail.com

1 / 29

New R 📦s for styling Shiny & R Markdown

{bslib}: tools for styling HTML from R (e.g., Shiny apps, rmarkdown::html_document(), etc)

{thematic}: simplified theming of R plots ({ggplot2}, {lattice}, & {base})

Not yet on CRAN (give it about a month or so)

remotes::install_github(c("rstudio/bslib", "rstudio/thematic"))
2 / 29

Start using {bslib} with Shiny

library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(),
...
)
  • fluidPage(), navbarPage(), bootstrapPage(), etc. all have this theme argument.

  • You may already be using theme with {shinythemes} or your own custom Bootstrap CSS.

    • bs_theme() is way more powerful!
3 / 29

By default, upgrades app to Bootstrap 4

library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(version = "4+3"),
...
)
  • bs_theme() defaults to version = "4+3", which means BS4 plus added compatibility for BS3.
    • Helps most Shiny apps & R Markdown docs upgrade to BS4.
    • Upgrading may break some custom widgets.
      • In that case, set version = 3.
4 / 29

Continue using Bootswatch themes

library(shiny)
library(bslib)
# In the past, this was shinythemes::shinythemes("darkly")
ui <- fluidPage(
theme = bs_theme(bootswatch = "darkly"),
...
)
  • Now you can use Bootswatch with BS4 or BS3 (just change version).
    • Bootswatch 4 has some new themes (e.g., solar and minty)
5 / 29

Preview a theme

bs_theme_preview(
bs_theme(bootswatch = "darkly")
)

6 / 29

Customize main colors and fonts!

bs_theme_preview(bs_theme(
bg = "black", fg = "white",
primary = "red", base_font = "Grandstander"
))

7 / 29

Use a better palette (e.g., material dark)

bs_theme_preview(bs_theme(
bg = "#202123", fg = "#B8BCC2",
primary = "#EA80FC", base_font = "Grandstander"
))

8 / 29

Tempering bs_theme() expectations

  • "Just works" with:

    • HTML that doesn't clash with Bootstrap CSS styling
  • "Just works" soon with:

    • All of Shiny (e.g., navbarPage(), sliderInput(), etc)
    • rmarkdown::html_document(), DT::datatable(), other popular {htmlwidgets}
    • Your custom component?
  • Can't work with things not rendered by web browser (e.g., plotOutput()).

    • Use {thematic} to "translate" CSS to R plots!
9 / 29

Plots don't reflect bs_theme() 😭

fluidPage(
theme = bs_theme(bg = "#002B36", fg = "#EEE8D5", primary = "#2AA198", base_fonts = "Pacifico"),
tabsetPanel(type = "pills", tabPanel("ggplot", plotOutput("ggplot")), tabPanel("lattice", plotOutput("lattice")), tabPanel("base", plotOutput("base")))
)

10 / 29

{thematic} to the rescue! 🎉

thematic::thematic_shiny()
fluidPage(
theme = bs_theme(bg = "#002B36", fg = "#EEE8D5", primary = "#2AA198", base_fonts = "Pacifico"),
tabsetPanel(type = "pills", tabPanel("ggplot", plotOutput("ggplot")), tabPanel("lattice", plotOutput("lattice")), tabPanel("base", plotOutput("base")))
)

11 / 29

The {thematic} package, in general

  • {thematic} alters R plotting defaults using a few simple settings. Use thematic_on() to enable globally (until thematic_off() is called).
library(thematic)
library(ggplot2)
thematic_on(
bg = "black",
fg = "white",
accent = "red",
font = "Indie Flower"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

12 / 29

The {thematic} package, in general

  • {thematic} alters R plotting defaults using a few simple settings. Use thematic_on() to enable globally (until thematic_off() is called).
library(thematic)
library(ggplot2)
thematic_on(
bg = "black",
fg = "white",
accent = "red",
font = "Indie Flower"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

Since Indie Flower is a Google Font, {thematic} installs it if needed!

13 / 29

Auto-theming with {thematic}

  • Main colors and fonts can be "auto"-detected!
library(thematic)
library(ggplot2)
thematic_on(
bg = "auto",
fg = "auto",
accent = "auto",
font = "auto"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

14 / 29

Auto-theming with {thematic}

  • Main colors and fonts can be "auto"-detected!
library(thematic)
library(ggplot2)
thematic_on(
bg = "auto",
fg = "auto",
accent = "auto",
font = "auto"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

"auto" works best via shiny::renderPlot() (works with any CSS, not just bs_theme())!

15 / 29

Auto-theming with {thematic}

  • Main colors and fonts can be "auto"-detected!
library(thematic)
library(ggplot2)
thematic_on(
bg = "auto",
fg = "auto",
accent = "auto",
font = "auto"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

"auto" can work with bs_theme() in rmarkdown::html_document()

16 / 29

Auto-theming with {thematic}

  • Main colors and fonts can be "auto"-detected!
library(thematic)
library(ggplot2)
thematic_on(
bg = "auto",
fg = "auto",
accent = "auto",
font = "auto"
)
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_smooth()

"auto" detects your RStudio Theme inside RStudio

17 / 29

That's enough about {thematic}, back to {bslib}

BTW, {thematic} also makes it easy to control qualitative and sequential colorscales.

18 / 29

Real-time theming

# Includes `bs_themer()`, an interactive widget for real-time theming!
bs_theme_preview(bs_theme(bg = "#202123", fg = "#B8BCC2", primary = "#EA80FC", base_font = "Grandstander"))
19 / 29

More targetted theming

bs_theme(
bg = "#002B36", fg = "#EEE8D5",
"progress-bar-bg" = "orange"
)

Beware, Sass variables can be quite different across versions!

20 / 29

What's Sass? What's a Sass variable?

  • Sass is a more powerful way to write CSS (i.e., style HTML)
  • Sass variables provide "high-level controls" over CSS
  • bs_theme() sets Bootstrap Sass variables (CSS compilation happens magically at run-time)

Learn more about Sass and the {sass} 📦 at https://rstudio.github.io/sass

21 / 29

Leverage the power of BS4 Utility Classes

Customize spacing, borders, modify colors, and more!

tabsetPanel(
tabPanel("One", "No padding"),
tabPanel("Two", "No padding")
)

tabsetPanel(
tabPanel(
"One", "With padding",
class = "p-3 border border-top-0 rounded-bottom"
),
tabPanel("Two", "No padding")
)

22 / 29

More generally, leverage the power of Sass

Add Sass rules to do things like @extend all navs to be centered

fluidPage(
theme = bs_theme() %>%
bs_add_rules(".nav { @extend .justify-content-center; }"),
tabsetPanel(
tabPanel("One", "Centered w/ padding", class = "p-3 border border-top-0 rounded-bottom"),
tabPanel("Two", "No padding")
)
)

23 / 29

Create custom, themable, components

person <- function(name, title, company) {
div(
class = "person",
h3(class = "name", name),
div(class = "title", title),
div(class = "company", company)
)
}
fluidPage(
person("Andrew Carnegie", "Owner", "Carnegie Steel Company"),
person("John D. Rockefeller", "Chairman", "Standard Oil"),
theme = bs_theme(bg = "#002B36", fg = "#EEE8D5") %>%
bs_add_rules(sass::sass_file("person.scss"))
)
.person {
display: inline-block;
padding: $spacer;
border: $border-width solid $border-color;
@include border-radius;
@include box-shadow;
outline: 0;
width: 300px;
@include media-breakpoint-down(sm) {
display: block;
width: auto;
margin-right: $grid-gutter-width;
}
margin: $grid-gutter-width;
margin-right: 0;
.title { font-weight: bold; }
.title, .company { color: $gray-600; }
}
.person:last-of-type {
margin-right: $grid-gutter-width;
}
24 / 29

Dynamic theming in Shiny w/ setCurrentTheme()!

dark <- bs_theme(bg = "black", fg = "white")
light <- bs_theme()
ui <- fluidPage(
theme = light,
checkboxInput("dark_mode", "Dark mode", FALSE)
)
server <- function(input, output, session) {
observe(session$setCurrentTheme(
if (input$dark_mode) dark else light
))
}
shinyApp(ui, server)

Very new and experimental (learn more)!

25 / 29

Use your theme inside R Markdown

Pass bs_theme() parameters to html_document() and html_document_base()1 (we hope to extend this to other output formats as well).

---
output:
html_document:
theme:
bg: "#202123"
fg: "#B8BCC2"
primary: "#EA80FC"
base_font: "Grandstander"
---
  1. Currently requires an experimental version of R Markdown remotes::install_github("rstudio/rmarkdown#1706")
26 / 29

Use your theme inside R Markdown

Customize the bs_theme() further with bs_global_*()

---
output:
html_document:
theme:
bg: "#202123"
fg: "#B8BCC2"
primary: "#EA80FC"
base_font: "Grandstander"
---
```{r, echo = FALSE}
library(bslib)
bs_global_add_rules(".nav { @extend .justify-content-center; }")
```
  1. Currently requires an experimental version of R Markdown remotes::install_github("rstudio/rmarkdown#1706")
27 / 29

Summary

  • Use {bslib} to style HTML in Shiny & R Markdown.

    • Upgrades to Bootstrap 4 by default (can also version = 3).
    • Customize main colors and fonts with bs_theme().
      • Also new defaults for more specific Sass variables
    • Leverage BS4 Utility Classes to customize spacing, borders, and more.
    • Include additional Sass rules with bs_add_rules()
      • Great for @extending Utility Classes or creating your own Bootstrap Sass styles!
  • Use {thematic} for easier theming of R plots

    • Works with {ggplot2}, plotly::ggplotly(), {lattice}, and {base} R graphics.
    • Auto-theming (i.e., translating CSS to R defaults) works great on Shiny, but can also specify colors and fonts directly in {thematic}.
28 / 29

New R 📦s for styling Shiny & R Markdown

{bslib}: tools for styling HTML from R (e.g., Shiny apps, rmarkdown::html_document(), etc)

{thematic}: simplified theming of R plots ({ggplot2}, {lattice}, & {base})

Not yet on CRAN (give it about a month or so)

remotes::install_github(c("rstudio/bslib", "rstudio/thematic"))
2 / 29
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow