Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
165 lines (127 sloc) 4.52 KB
---
title: "Introduction to Sass"
author: "Timothy Mastny"
date: "2018-08-14"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Introduction to Sass}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
CSS styling for [R Markdown](https://bookdown.org/yihui/rmarkdown/custom-css-1.html) and [Shiny](https://shiny.rstudio.com/articles/css.html) allows users to completely customize the appearance of their documentations and dashboards.
However, for some Shiny apps and R packages like [gt](https://github.com/rstudio/gt), styling needs to be dynamically generated based on user input.
The `sass` R package facilitates dynamic styling by compiling the CSS extension language [Sass](https://sass-lang.com), which allows CSS to be parameterized with variables, functions, and calculations.
This article will briefly demonstrate how to compile custom CSS in a live Shiny to change styling in response to user input.
## Variables
Sass variables are key to generating dynamic CSS, because they define the components of the styling that can be changed during compilation.
It is best practice to define your [variables](http://sass-lang.com/guide#topic-2) separately, and then [import](http://sass-lang.com/guide#topic-5) them into the main Sass file. For example, we'll define a color variable and use it to set the body's background color.
```css
/* _variables.scss */
$color: #FFFFFF;
```
```css
/* new-style.scss */
@import 'variables';
body {
background-color: $color;
}
```
The following [shiny app](https://gallery.shinyapps.io/sass-color) will demonstrate this example. We'll use Dean Attali's [colourpicker](https://github.com/daattali/colourpicker) to choose a color and write it to `_variables.scss`.
Then the app compiles `new-style.scss` and renders the new style.
```{r echo = FALSE}
knitr::include_app("https://gallery.shinyapps.io/sass-color", height = "600px")
```
## Functions
If we choose a background color that is too dark, we won't be able to read the title. Therefore, the font color must depend on the background color.
Sass offers many [built-in functions](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#functions) that help with dynamic styling, and you can always write [your own](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#function_directives).
```css
/* _variables.scss */
$color: #FFFFFF;
```
```css
/* new-style.scss */
@import 'variables';
body {
background-color: $color;
}
/* https://stackoverflow.com/a/3943023/6637133 */
@function font-color($color) {
@return if(
red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186,
#000000, #ffffff
);
}
h1 {
color: font-color($color);
}
```
In this [shiny example app](https://gallery.shinyapps.io/sass-font/), the font color now [depends](https://stackoverflow.com/a/3943023/6637133) on the background color, switching between black and white as necessary.
```{r echo = FALSE}
knitr::include_app("https://gallery.shinyapps.io/sass-font/", height = "400px")
```
## Resizing
Since Sass is fully CSS compatible, any styling option is available, including dimensions like height and width.
In this [example app](https://gallery.shinyapps.io/sass-size/) we'll change the width of the image based on a slider:
```css
/* _variables.scss */
$color: #FFFFFF;
$width: 100;
```
```css
/* new-style.scss */
@import 'variables';
body {
background-color: $color;
}
// https://stackoverflow.com/a/3943023/6637133
@function font-color($color) {
@return if(
red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186,
#000000, #ffffff
);
}
h1 {
color: font-color($color);
}
.shiny-plot-output {
max-width: percentage($width / 100);
}
```
```{r echo = FALSE}
knitr::include_app("https://gallery.shinyapps.io/sass-size/", height = "600px")
```
## CSS Formatting
Sass can also format the CSS output with different indentation styles.
Here we'll convert the readable Sass to minified CSS.
```{r}
new_style <- "
$color: #FFFFFF;
$width: 100;
body {
background-color: $color;
}
// https://stackoverflow.com/a/3943023/6637133
@function font-color($color) {
@return if(
red($color) * 0.299 + green($color) * 0.587 + blue($color) * 0.114 > 186,
#000000, #ffffff
);
}
h1 {
color: font-color($color);
}
.shiny-plot-output {
max-width: percentage($width / 100);
}
"
```
```{r}
library(sass)
sass(new_style, options = sass_options(output_style = "compressed"))
```
You can’t perform that action at this time.