Style your apps with CSS

You can give your Shiny app a special look with cascading style sheets (CSS).

CSS is a style language which gives HTML documents a sophisticated look. Since the Shiny app user-interface (UI) is an HTML document, you can use CSS to control how you want your Shiny app to look.

The CSS language is easy to learn and widely used. If you would like to learn CSS code, I recommend the free interactive codecademy tutorial. There is also a free concise tutorial at udemy.com.

In this article, I describe the three ways Shiny works with CSS. To get CSS into your Shiny App, you can:

  1. Add style sheets with the www directory
  2. Add CSS to your HTML header
  3. Add styling directly to HTML tags

These methods correspond to the three ways that you can add CSS to an HTML document. In HTML, you can:

  1. Link to a stylesheet file
  2. Write CSS in the document’s header, and
  3. Write CSS in the style attribute of an HTML element.

Recall that the C in CSS refers to “cascading”. CSS in a style attribute will overrule CSS in a document’s header, which will overrule CSS in an external file. This cascading arrangement lets you create global style rules (in an external file, or header), and special cases (elements that have their own style attribute).

1. Add style sheets with the www directory

These two ‘New Application’ Shiny apps are identical, except for the appearance of the UI. The basic one on the left is the default Shiny App. The one on the right uses a CSS file to enhance its look.

You can apply a CSS file to your entire Shiny app by linking to it from within your Shiny App.

  • Create a subdirectory named www in your Shiny app directory. This subdirectory name www is special. Shiny makes every file in www available to your user’s browser. The www subdirectory is a great place to put CSS files, images, and other things a browser needs to build your Shiny App.
  • Place your CSS file in the www subdirectory.

For this UI change, I am using a CSS file named bootstrap.css. I downloaded it from Bootswatch, a great place to get free CSS themes for bootstrap webpages.

Note: The Shiny UI is built with the Bootstrap 3.3.1 HTML/CSS framework. CSS files designed to work with Bootstrap 3.3.1 will work best with Shiny.

After you get bootstrap.css and put it in your www subdirectory, your Shiny app directory should look like mine:

Once your Shiny app directory is set, you have two choices to link to your CSS file (your app won’t use the CSS until you do). You can:

  1. set the theme argument of fluidPage to your document’s name or
  2. include the file with the tags object.

The theme argument

The simplest choice is to set the theme argument of fluidPage to your document’s name (as a character string). Your ui.R script will look like the following code:

shinyUI(fluidPage(theme = "bootstrap.css",
  
  headerPanel("New Application"),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

I used this code to make the ‘New Application’ Shiny app on the right. To make the default Shiny app (the one on the left), remove theme = "bootstrap.css".

You can link to the CSS file with the tags object too. tags recreates popular HTML tags, and has its own article here.

The standard way to link to a CSS file in an HTML document is with a link tag embedded inside a head tag. For example, you might write an HTML document like the one below:

<!DOCTYPE html>
<html>
  <head>
    <link type="text/css" rel="stylesheet" href="bootstrap.css"/>
  </head>
  <body>
  </body>
</html>

You can recreate this arrangement in Shiny with:

shinyUI(fluidPage(

  tags$head(
    tags$link(rel = "stylesheet", type = "text/css", href = "bootstrap.css")
  ),

  headerPanel("New Application"),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

This code will make the ‘New Application’ Shiny app on the right.

Notice that bootstrap.css is stored in the www subdirectory. You do not need to add www/ to the file path that you give href. Shiny places the files in your Shiny App’s home directory before sending them to your user’s browser.

Remember that I said www is a special subdirectory name and important to use. Shiny will share a file with your user’s browser if the file appears in www. Shiny will not share files that you do not place in www.

Both the theme argument of fluidPage and the href argument of tags$link can point to a URL (that contains a CSS file). You may find this method a convenient way to share the same CSS file across many Shiny apps.

2. Add CSS to your HTML header

You can also add add CSS directly to your Shiny UI. This is the equivalent of adding CSS to the head tag of an HTML document. This CSS will override any CSS imported from an external file (should a conflict arise).

As before, you have two options for adding CSS at this level. You can

  1. Add CSS with tags, or
  2. Include a whole file of CSS with includeCSS

Add CSS to the header with tags

Use tags$style instead of tags$link to include raw CSS. Write the CSS as a character string wrapped in HTML() to prevent Shiny from escaping out HTML specific characters.

As with tags$link, nest tags$style inside of tags$head.

shinyUI(fluidPage(

  tags$head(
    tags$style(HTML("
      @import url('//fonts.googleapis.com/css?family=Lobster|Cabin:400,700');
      
      h1 {
        font-family: 'Lobster', cursive;
        font-weight: 500;
        line-height: 1.1;
        color: #48ca3b;
      }

    "))
  ),
    
  headerPanel("New Application"),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

This code makes the following Shiny App. Note that I changed only the title’s appearance.

Add CSS to the header with includeCSS

If you have CSS saved in a file, you can add it to the header of your Shiny app with includeCSS.

Shiny will place the contents of the file into the header of the HTML document it gives to web browsers, as if you had used tags$style. You do not need to save the file in www. Shiny will expect it in your Shiny app directory unless you specify otherwise.

For example, I’ve placed a lightweight style sheet named styles.css in my app directory below.

This CSS file changes the title of a Shiny app and nothing else. Here is the actual CSS saved in the file.

@import url("//fonts.googleapis.com/css?family=Lobster|Cabin:400,700");

h1 {
  font-family: 'Lobster', cursive;
  font-weight: 500;
  line-height: 1.1;
  color: #ad1d28;
}

body {
  background-color: #fff;
}

The code below includes styles.css to make the app in the next image.

shinyUI(fluidPage(

  includeCSS("styles.css"),
    
  headerPanel("New Application"),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

3. Add styling directly to HTML tags

You can add CSS styling directly to individual HTML elements in your UI, just as you add styling directly to HTML tags in a web document. CSS provided at this level takes precedence over any other sources of CSS (should a conflict occur).

To add CSS to an individual element, pass it to the style argument of the Shiny function that you use to create that element.

In the script below, I set the style of the title of the Shiny app with the style argument of h1 in headerPanel. The style relies on a font that I import with tags$style in tags$head.

shinyUI(fluidPage(

  tags$head(
    tags$style(HTML("
      @import url('//fonts.googleapis.com/css?family=Lobster|Cabin:400,700');
    "))
  ),
    
  headerPanel(
    h1("New Application", 
      style = "font-family: 'Lobster', cursive;
        font-weight: 500; line-height: 1.1; 
        color: #4d3a7d;")),
  
  sidebarPanel(
    sliderInput("obs", "Number of observations:", 
                min = 1, max = 1000, value = 500)
  ),
  
  mainPanel(plotOutput("distPlot"))
))

Here’s what the Shiny app looks like with this code:

Recap

Add CSS to a Shiny UI just as you would add CSS to a web page.

To get CSS into your Shiny App, you can:

  1. Link to an external CSS file
  2. Include CSS in the header of the web page that the app is built on, or
  3. Pass style information to individual HTML elements in your app.

My examples give a glimpse into the options CSS offers your Shiny App. Explore more at Bootswatch and see what you can create.



We love it when R users help each other, but RStudio does not monitor or answer the comments in this thread. If you'd like to get specific help, we recommend the RStudio Community as well as the Shiny Discussion Forum for in depth discussion of Shiny related questions and How to get help article for a list of the best ways to get help with R code.

comments powered by Disqus

Start
Build
Improve