EDS 430: Part 4.1

Theming and styling apps with {bslib} & {fresh}


Creating custom themes

We’ve built some really cool apps so far, but they all have a pretty standard and similar appearance. In this section, we’ll explore two packages for creating custom themes for your apps.

Learning Objectives - Themeing/Styling Apps


By the end of this section, you should be equipped with:

an understanding of how to use packaged-based tooling for themeing and styling your shiny apps and dashboards


Packages introduced:

{bslib}: provides tools for customizing Bootstrap themes directly from R for shiny apps and RMarkdowns

{fresh}: provides tools for creating custom themes for use with shiny, shinydashboard, and bs4Dash apps

Using the {bslib} package to theme Shiny apps


The {bslib} package provides a modern UI toolkit for Shiny and R Markdown based on Bootstrap, making custom themeing for Shiny apps (and R Markdown docs!) quite easy.


Pros:

easy to use

includes a real-time themeing widget to try out themes before applying them to your own app

plays well with the {thematic} package for matching plot styling to app

{bslib} does more than just themeing! Read more on their pkgdown site

Cons:

does not work with shinydashboard ({bslib} is only intended for use with shiny apps), though one of the latest releases includes tooling to create and customize dashboard-style shiny apps – check out their vignette for more

styling is constrained by the arguments available to bs_theme()


Let’s practice applying new themes using bslib to our one-file-app (i.e. App #1)

Apply a pre-built theme with {bslib}


By default, Shiny uses the Bootstrap v3 theme (which is not so exciting). Change the theme to a slightly more modern Bootstrap v5 theme by setting the theme argument of fluidPage() to bslib::bs_theme(version = 5), or supply bs_theme() with a pre-built bootswatch theme, as shown below (for a list of theme names, run bootswatch_themes() in your console):


~/single-file-app/ui.R
library(shiny)
library(bslib)
# ~ additional libraries omitted for brevity ~

ui <- fluidPage(
  
  theme = bs_theme(bootswatch = "solar"),
  
  # ~ additional UI code omitted for brevity ~
  
)

Check out the complete source code for App #1 (NOTE: applied themes are commented out).

A shiny app depicting a title, subtitle sliderInput, scatterplot, checkboxGroupInput, and DT datatable, all stacked vertically. The pre-build bootswatch 'solar' theme has been applied, turning the background color dark blue and changing widget colors to dark gray or yellow. The background of the scatterplot is still white.

Create a custom theme with {bslib}


Alternatively, you can fully customize your own theme. Explore the bslib pkgdown site for detailed instructions. A small example here:

~/single-file-app/ui.R
library(shiny)
library(bslib)
# ~ additional libraries omitted for brevity ~

ui <- fluidPage(
  
  theme = bs_theme(
    bg = "#A36F6F", # background color
    fg = "#FDF7F7", # foreground color
    primary = "#483132", # primary accent color
    base_font = font_google("Pacifico")),
  
  # ~ additional UI code omitted for brevity ~
  
)

Check out the complete source code for App #1 (NOTE: applied themes are commented out).

A shiny app depicting a title, subtitle sliderInput, scatterplot, checkboxGroupInput, and DT datatable, all stacked vertically. A custom theme, created using bs_theme() has been applied, turning the background color pink, changing widget colors to a dark magenta, and applying a cursive white font styling to all text. The background of the scatterplot is still white.

Be sure to check out the interactive themeing widget to test custom color / font / etc. combos by running bs_theme_preview() in your console, or visit the hosted version. You can also call bs_themer() within your server function to open the theme customization UI alongside your own app.

Use {thematic} to extend your theme to plots


You probably noticed that our scatterplot looks a little silly against the darker background of our themed app. Enter the {thematic} package, which is built to help simplify plot themeing. Call thematic_shiny() before launching your app to generate plots that reflect your application’s bs_theme(). For example:

~/single-file-app/ui.R
library(shiny)
library(bslib)
# ~ additional libraries omitted for brevity ~

thematic::thematic_shiny()

ui <- fluidPage(
  
  theme = bs_theme(
    bg = "#A36F6F", # background color
    fg = "#FDF7F7", # foreground color
    primary = "#483132", # primary accent color
    base_font = font_google("Pacifico")),
  
  # ~ additional UI code omitted for brevity ~
  
)

Check out the complete source code for App #1 (NOTE: applied themes are commented out).

A shiny app depicting a title, subtitle sliderInput, scatterplot, checkboxGroupInput, and DT datatable, all stacked vertically. A custom theme, created using bs_theme() has been applied, turning the background color pink, changing widget colors to a dark magenta, and applying a cursive white font styling to all text. The background of the scatterplot is now the same color (pink) as the background.

Check out the pkgdown site to learn more about using {thematic} to match plot fonts to the fonts applied across your app.

Using the {fresh} package to theme Shiny apps & dashboards


The {fresh} package provides tools for creating custom themes to use in Shiny apps and dashboards – set parameters of your theme using create_theme(), generate a stylesheet based off your specifications, and apply your stylesheet to your app.


Pros:

easy to use

supports theme creation for both shiny apps and dashboards (and also {flexdashboard}s and {b4dash} applications)

Cons:

styling is constrained by the variables available to create_theme()


Let’s practice applying new themes using {fresh} to our two-file-app (i.e. App #2) and our shinydashbaord (i.e. App #3)

A general workflow for using fresh themes


Whether you’re working on a shiny app or a shiny dashboard, you’ll need the following:

(1) a www/ folder within your app’s directory – this is where we’ll save the stylesheet (a .css file) that {fresh} will generate for us

(2) a separate script for building our theme using the create_theme() function – I recommend saving this to scratch/ (it seemed to cause issues when saved anywhere within my app directory)


Importantly, create_theme() takes different variables to set the parameters of your theme, depending on what type of app you’re building: for shiny apps, you’ll need to use bs_vars_* variables, and for shiny dashboards you’ll use adminlte_* variables (examples on the following slides).

There are also a couple ways to apply your finished theme to your app, but we’ll use the method of generating a .css file, then calling that file in our app.

Creating a fresh theme for two-file-app


In this example, we update the colors of our app’s body, navbar, and tabPanels using the appropriate {fresh} variables for shiny apps. We specify a file path, two-file-app/www (you’ll need to create the www/ directory, since we don’t have one yet), where our stylesheet (e.g. shiny-fresh-theme.css, as shown here) file will be saved to. Of course, these color combos are not recommended, but chosen purely for demonstration purposes .

~/R/create-fresh-theme-shiny.R
# load library ----
library(fresh)

# create theme -----
create_theme(
  
  theme = "default", # you can supply a bootstrap theme to begin with
  
  bs_vars_global( # global styling
    body_bg = "#D2D0CA", # beige
    text_color = "#F23ACB", # hot pink
    link_color = "#0E4BE3" # royal blue
  ),
  
  bs_vars_navbar( # navbar styling
    default_bg = "#13CC13", # lime green
    default_color = "#66656C" # gray
  ),
  
  bs_vars_tabs( # tab styling
    border_color = "#F90909" # red
  ),
  
  output_file = "two-file-app/www/shiny-fresh-theme.css" # generate css file & save to www/
)

Apply a fresh theme to our app


To apply our theme, provide the theme argument of your fluidPage() or navbarPage() with the name of our stylesheet. Note: shiny knows to look in the /www directory, so you can omit that from your file path, as shown below:



~/two-file-app/ui.R
# navbar page ----
ui <- navbarPage(

  theme = "shiny-fresh-theme.css",
  
  # ~ additional UI code omitted for brevity ~
  
) # END navbarPage

Check out the complete source code for App #2 (NOTE: applied themes are commented out).

An app with a tan-colored background, lime green navbar, bright pink text, and blue links, showcasing how different components of a shiny app can be modified using the fresh packages.

Creating a fresh theme for our shinydashboard


In this example, we update the colors of our app’s header, body, and sidebar using the appropriate fresh variables for shiny dashboards. We specify a file path, shinydashboard/www/ where our stylesheet (e.g. shinydashboard-fresh-theme.css, as shown here) file will be saved to. Again, these color combos are not recommended, but chosen purely for demonstration purposes.

~/R/create-fresh-theme-shinydashboard.R
# load libraries ----
library(fresh)

# create theme ----
create_theme(
  
  # change "light-blue"/"primary" color
  adminlte_color(
    light_blue = "#150B5A" # dark blue
  ),
  
  # dashboardBody styling (includes boxes)
  adminlte_global(
    content_bg = "#E7B5B5" # blush pink
  ),
  
  # dashboardSidebar styling
  adminlte_sidebar(
    width = "400px", 
    dark_bg = "#57F8F3", # light blue
    dark_hover_bg = "#BF21E6", # magenta
    dark_color = "#F90000" # red
  ),
  output_file = "shinydashboard/www/shinydashboard-fresh-theme.css" # generate css file & save to www/
)

Apply a fresh theme to our dashboard


To apply our theme, use the fresh::use_theme() function inside your dashboardBody, providing it with the name of your stylesheet. Note: shiny knows to look in the www/ directory, so you can omit that from your file path, as shown below:



~/shinydashboard/ui.R
body <- dashboardBody(
  
  # set theme
  fresh::use_theme("shinydashboard-fresh-theme.css"),
  
  # ~ additional dashboardBody code omitted for brevity ~
  
)

Check out the complete source code for the shinydashboard (NOTE: applied themes are commented out).

A shinydashboard with a dark blue dashboardHeader, pink dashboardBody, light blue dashboardSidebar, red sidebar text, and bright pink sidebar menuItem highlights, showcasing how shinydashboards can be customized using the fresh package.

End part 4.1

Up next: fully custom themes using CSS & Sass

05:00