Chapter 18 A Gentle Introduction to CSS
18.1 What is CSS
18.1.1 About CSS
CSS, for Cascading Style Sheets
, is one of the main technologies that powers the web today, along with HTML and JavaScript.
HTML is a series of tags that define your web page structure, and JavaScript is a programming language that allows you to manipulate the page (well, it can do a lot more than that, but we are simplifying to make it understandable).
CSS is what handles the design, i.e. the visual rendering of the web page: the color of the header, the font, the background, and everything that makes a web page look like it is not from 1983 (again, we are simplifying for the sake of clarity).
On every browser, each HTML element has a default style: for example all <h1>
have the size 2em
and are in bold, and <strong>
is in bold.
But we might not be happy with what a “standard page” (with no CSS) looks like: that is the very reason of CSS, modifying the visual rendering of the page.
If you want to get an idea of the importance of CSS, try installing extensions like Web Developer for Google Chrome. Then, if you go on the extension and choose CSS, click “Disable All Style”, to see what a page without CSS looks like.
For example, here is what rtask.thinkr.fr looks like:
And here is what it looks like without CSS:
CSS now seems pretty useful right?
18.1.2 {shiny}
’s default: fluidPage()
In {shiny}
, there is a default CSS: the one from Bootstrap 3.
As you can see if you have created a fluidPage()
before, there is already styling applied.
Compare:
(no fluidPage
)
library(shiny)
ui <- function(){
tagList(
h1("Hey"),
h2("You"),
p("You rock!"),
selectInput("what", "Do you", unique(iris$Species))
)
}
server <- function(
input,
output,
session
){
}
shinyApp(ui, server)
to (with fluidPage
):
library(shiny)
ui <- function(){
fluidPage(
h1("Hey"),
h2("You"),
p("You rock!"),
selectInput("what", "Do you", unique(iris$Species))
)
}
server <- function(
input,
output,
session
){
}
shinyApp(ui, server)
Yes, that is subtle, but you can see how it makes the difference on larger apps.
18.2 Getting started with CSS
CSS is a descriptive language, meaning that you will have to declare the style either on a tag or inside an external file.
We will see how to integrate CSS inside your {shiny}
application in the next section, but before that, let’s start with a short introduction to CSS72 .
18.2.1 About CSS syntax
CSS syntax is composed of two elements: a selector, and a declaration block. The CSS selector describes how to identify the HTML tags that will be affected by the style declared with key-value pairs in the declaration block that follows. And because an example will be easier to understand, here is a simple CSS rule:
Here, the selector is h2
, meaning that the HTML tags aimed by the style are the <h2>
tags.
The declaration block contains the key-value pair telling that the color
will be red
.
Note that each key-value pair must end with a semicolon.
18.2.2 CSS selectors
CSS selectors are a wide topic, as there are many combinations of things you might want to select inside an HTML page.
The first type of selectors are the “standard” ones name
, id
, or class
.
These refer to the elements composing an HTML tag: for example, with <h2 id = "tileone" class = "standard">One</h2>
, the name is h2
, the id tileone
, and the class standard
73 .
To select these three elements in CSS:
- Write the name as-is:
h2
- Prefix the id with
#
:#tileone
- Prefix the class with
.
:.standard
You can also combine these elements, for example h2.standard
will select all the h2
tags with a class standard
, and h2,h3
will select the h2
and the h3
.
You can build more complex selectors: for example div.standard > p
will select all the <p>
tags that are contained inside a div
of class standard
(CSS combinator), or a:hover
, which dictates the style of the a
tags when they are hovered by the mouse (CSS pseudo-class), div.standard::first-letter
, that select the first letter of the div
of class standard
(CSS pseudo-elements), and h2[data-value="hey"]
, which selects all the h2
with a data-value
attribute set to "hey"
(CSS attribute selector).
As you can see, lots of complex selectors can be built with CSS, to target very specific elements of your UI. But mastering these complex selectors is not the main goal of this chapter, hence we will just be using standard selectors in the rest of the examples in this book.
18.2.3 CSS properties
Now that you have selected elements, it is time to apply some styles! Between the brackets of the declaration block, you will have to define a series of key-value elements defining the properties of the style: the key here is the css property, followed by its value.
For example, color: red;
or text-align: center;
define that for the selected HTML elements, the color will be red, or the text centered.
We will not cover all the possible properties, as there hundreds of them.
Feel free to refer to the CSS Reference page from Mozilla for an exhaustive list of available properties.
18.3 Integrate CSS files to your {shiny}
App
Now that you have an idea of how to start writing your own CSS, how do you integrate it into your {shiny}
Application?
There are three methods that can be used: writing it inline, integrating it inside a tags$script()
straight into you application UI code, or by writing it into an external file.
Note that the good practice is considered to be the integration of an external file.
18.3.1 Inline CSS
If you need to add style to one specific element, you can write it straight inside the HTML tag:
library(shiny)
ui <- function(){
tagList(
h2(style = "color:red;", "This is red")
)
}
server <- function(
input,
output,
session
){
}
shinyApp(ui, server)
But this method loses all the advantages of CSS, notably the possibility to apply style to multiple elements. Use it with caution.
18.3.3 Including External Files
To include an external CSS file, you will have to use another tag: tags$link()
.
What this tag will contain is these three elements:
rel="stylesheet"
type="text/css"
href="www/custom.css"
The first two are standard: you do not need to change them, they are necessary to indicate to the HTML page that you are creating a stylesheet, with the type being text/css.
The href
is the one you will need to change: this path points to where your style file is located.
If you are building your application with {golem}
(Fay et al. 2020), the good news is that this file creation and linking is transparent: if you call golem::add_css_file("name")
, a file will be created at inst/app/www
, and this file will be automatically linked inside your UI thanks to the bundle_resources()
function.
18.3.4 Using R packages
If you want to use external CSS template, there are several packages that exist that can implement new custom UI designs for your application. Here are some:
{resume}
(Fay 2020j), provides an implementation of the Bootstrap Resume Template.{skeleton}
(Fay 2020k), Skeleton CSS.{shinyMobile}
(Granjon, Perrier, and Rudolf 2019), shiny API for Framework7 (IOS/android).{shinydashboardPlus}
(Granjon 2019b), extensions for shinydashboard.{bs4Dash}
(Granjon 2019a), Bootstrap 4 shinydashboard using AdminLTE3: an example if available at engineering-shiny.org/bs4dashdemo/{fullPage}
(Coene 2020a), fullPage.js, pagePiling.js and multiScroll.js for shiny.
And all the amazing things done at RinteRface.
18.4 External resources
If you want to learn more about CSS, there are three places where you can get started:
FreeCodeCamp, with contains many hours of course around HTML and CSS.
References
Coene, John. 2020a. FullPage: Three Families of Functions for Three Different Single Page Shiny Apps. https://github.com/RinteRface/fullPage.
Fay, Colin. 2020i. Nessy: A Nes Css for Shiny. https://github.com/ColinFay/nessy.
Fay, Colin. 2020j. Resume: Bootstrap Resume Template for Shiny.
Fay, Colin. 2020k. Skeleton: Skeleton Css for Shiny.
Fay, Colin, Vincent Guyader, Sébastien Rochette, and Cervan Girard. 2020. Golem: A Framework for Robust Shiny Applications. https://github.com/ThinkR-open/golem.
Granjon, David. 2019a. Bs4Dash: A Bootstrap 4 Version of Shinydashboard.
Granjon, David. 2019b. ShinydashboardPlus: Add More Adminlte2 Components to Shinydashboard.
Granjon, David, Victor Perrier, and Isabelle Rudolf. 2019. ShinyMobile: Mobile Ready Shiny Apps with Standalone Capabilities.