
Carson Sievert || Custom Theming with {bslib} in Shiny and R Markdown using bs_theme() || RStudio
00:00 Introduction 01:15 Jumping right in with the theme argument in Shiny 01:31 Shiny's classic navbarPage using bs_theme() 01:46 Specifying your Bootstrap version 02:31 Using the theme argument in R Markdown 03:17 Custom theming in R Markdown using bs_theme() 04:10 bslib templates provided by RStudio 05:33 Review of common arguments for the theme parameter 08:47 Tips for working with dark themes 10:34 Introduction to the thematic package, which styles plots 12:04 How thematic handles fonts 13:09 Using fonts with bslib in R Markdown 14:36 Moving a theme from an R Markdown document into a Shiny app 16:51 Setting warnings for contrast ratios 18:42 A quick tour of Bootstrap 4 and Bootstrap 5 Sass variables 20:35 A quick overview of writing custom HTML in Shiny 22:15 How bslib automatically handles color contrast ratios bs_theme() allows you to creates a Bootstrap theme object, where you can choose a (major) Bootstrap version, choose a Bootswatch theme (optional), customize main colors and fonts via explicitly named arguments (e.g., bg, fg, primary, etc), and customize other, lower-level, Bootstrap Sass variable defaults via .... You can read more about the bslib package here: https://rstudio.github.io/bslib/ And you can learn more about Shiny here: https://shiny.rstudio.com/ Got questions? The RStudio Community site is a great place to get assistance: https://community.rstudio.com/ Content: Carson Sievert (@cpsievert) Design and editing: Jesse Mostipak (@kierisi)
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
The nice thing about learning bslib is it serves as a general foundation that not only Shiny and R Markdown directly can use, but also extension packages like flex-dashboard and package-down and book-down, like some of these other packages that fit in an ecosystem and essentially like extend R Markdown or extend Shiny.
Because of how we've sort of approached this problem, at least a handful of these packages have pretty nice seamless integration with the ability to, like, if you have a theme that you're already using for your Shiny application, you can pretty easily sort of copy-paste that over to a flex-dashboard app or your package-down website or something like that.
If you're using bslib, make sure you have a more recent version of Shiny and R Markdown when you're using it.
Basic usage with the theme argument
And the real straightforward basic usage is to take advantage of this theme argument. If we're talking about Shiny, there's a few different ways to create sort of the page container. So if you want that classic navbar-page look, you would start with navbar-page and give the theme argument to this bs-theme object.
And with this bs-theme function, you can specify the bootstrap version that you want to use. So I think still we're defaulting to bootstrap 4, but soon we will default to bootstrap 5. But if you want your project to be fully reproducible, we do recommend, like, fully specifying the version so that if we change the default in the future, you won't be surprised that you're getting a new bootstrap version.
So this is kind of like the easiest way to opt in to a new bootstrap version is to call this bs-theme function, give it a version, and pass it to the theme argument of a page layout.
And the equivalent way of doing something like this in R Markdown is to work with the theme arguments of a output format. So not all output formats will have a theme argument. This historically has just been used for output formats that are HTML-based. And theme has historically meant, like, choose a different boot swatch theme, essentially. So you might have used this and said something like theme darkly or theme cyborg or some boot swatch theme.
But we've now extended this interface, essentially, with bslib so that you can provide any collection of arguments to this bs-theme function with all of your custom theming parameters. And then, essentially, this HTML document will use all of those custom settings to influence the CSS that goes on the page in the same way that would happen for the navbar page. That's one of the great things about learning bslib once is you can use it in both of those projects.
That's one of the great things about learning bslib once is you can use it in both of those projects.
You just have to kind of work around the fact that this is YAML and not R code. So some of the things that you might be more easily done over here in the R side might be a little bit trickier to convert that to pure YAML.
bslib templates in RStudio
If you have more recent versions of bslib and Flex Dashboard, bslib itself comes with some different templates in RStudio. So I could show you how that looks. If I go to file, new file in RStudio, and then go to R Markdown, this little window will pop up. And then if you choose the from template option, bslib will provide a few different sort of examples of how to get started with R Markdown.
And I believe, I don't know if I have the newest version of Flex Dashboard, but we also have some Flex Dashboard templates that show you how to use bslib with it. So if I just open that one, this will give me like a more worked out, complete theme.
Common theme arguments
And so it's not going to be super clear or super obvious. Like one unfortunate way about how this currently works, which we're looking to improve in the future, is that I don't like, how am I going to remember what arguments go to this theme parameter?
You know, I'm using bg here, which represents the background color, fg, which represents the foreground color, a primary color, secondary, and a couple different font settings. And I guess the way that I keep track of this, and I'm hoping other people will remember this as well, is you can pass in any argument to this bs-theme function to this theme YAML setting over here.
So as you can see, the first few listed are the bg, as I said, a color string for the background, fg, color string for the foreground. There's a handful of different like accent color settings. So primary is going to be, you know, the most obvious one that changes the most colors, but then it's also possible to control some other colors with these other accents.
There's three different main settings for fonts. So the base font is going to be kind of like the global font setting for everything on the page. Code will target, you know, like code blocks, essentially, headings for things like titles. And then you can also do some things like scale the fonts to larger sizes.
And eventually we'll get through, talk about like the fact that there's actually hundreds of different theming controls that you have access to via bslib, but they're not all named arguments. And we've kind of intentionally designed things that way, where we want to allow you to set any of these sort of main color and font settings and have it work across the board on all Bootstrap versions.
But then when you get more targeted and, you know, set a more specific style on a very particular thing on a website, we want to make it a little bit harder to discover those things and make you aware of the fact that this could potentially break with a newer version of Bootstrap and we're not like committing to supporting this across the board.
Tips for working with dark themes
So let me actually just show you a real example of what's going on here. So let me just knit this. All right. So this is the template or the result of that template. So that main BG setting is going in and determining like this background color here, the foreground color, I believe, will be used for these text colors here.
And the thing about, you know, implementing a dark theme like this that you might want to keep in mind is, you know, there's actually at least tens, if not hundreds, of actual color styles that are going into the end result on the page. So, for example, like the gray on this background for this code block is actually like a mixture between the background and the foreground color that you're choosing.
So when you give us those two main settings, you want it to be kind of a high contrast difference between probably two like grayscale colors. So that's why, you know, I kind of recommend, you know, first of all, it's primarily most useful for just implementing a dark theme like this, where you just set the background to something that's close to black and foreground that's something close to white. Then you can easily have a dark theme here.
But I think people quickly want to like set like colors with different hues, like a green for a background or something like that. And just be careful, like if you want to do something like that, you want to set a dark green, like choose a lighter green for the foreground color and don't choose like a light red or something like that, because you'll get mixtures of those two colors to determine stuff like these code blocks.
Introduction to thematic
Also, I've kind of already jumped one of the punch lines here where this template is also showing you another package that could be kind of thought of as like a sister package to bslib called thematic, which essentially allows you to pretty easily translate on some level the CSS styles that are going onto the page and have those styles actually determine new global styling defaults for your R plots.
So, to make that happen, I just called thematic RMD, since this is an R markdown document, thematic has a thematic RMD, where this extra setting will also make it so that it uses the font settings that I've set up here in this document as well to use that for the fonts that are in the plot.
And the reason why this isn't really enabled by default is that, you know, chances are you don't actually have the font installed in your R graphics device. So thematic will actually, in the case that it's detected that you don't have that font installed, it will actually go out and grab fonts from Google's font API.
So if you're not familiar, there's a fonts.google.com that provides you access to like hundreds, if not thousands of different free fonts. Essentially, we've tried to design both bslib and thematic in the sense of like, if you can find the font on this fonts.google.com, you don't have to do any other work beyond just specifying the font, and we'll do all the work of downloading and caching and making sure that that font is actually available when people try to view your website. So there's a lot of work to make that all that magic happen in the background, if you've ever worked with fonts before.
Essentially, we've tried to design both bslib and thematic in the sense of like, if you can find the font on this fonts.google.com, you don't have to do any other work beyond just specifying the font, and we'll do all the work of downloading and caching and making sure that that font is actually available when people try to view your website.
Using Google fonts with bslib in R Markdown
And I kind of glossed over the fact that there is kind of a special way to use Google fonts with bslib. If you're inside of our markdown, you first, you know, you're going to have to go to the markdown, you first use this bstheme function and, you know, remind yourself, oh, yeah, I want to change the base font.
And if you want to use this with the normal R programming usage, you have to remember, oh, I want to actually use this font in Google Helper, and then give the family name. And that's just kind of an indication to tell bslib, hey, this is actually, you know, a font that I want you to make sure, like, the font files are actually included with the end website and are actually, you know, made available and used for that base font setting.
Because if you were to do it this way, it would just change the CSS style without actually bringing in any of the actual font files needed to render that font. So, yeah, that's an important distinction to remember, that this is the way you would want to specify something like this on the R side, like with Shiny. But this is the way you specify it in our markdown.
Moving a theme from R Markdown into Shiny
Let me just go back to, like, a more simple example with Shiny. So, this is kind of like the example we saw on the homepage for bslib. And let's just, you know, create a navbar page with the typical navbar page usage. So, this is just a simple Shiny app where I have two tabs here, A and B, and I can click back and forth to look at page A and page B.
And that's fine. That works just fine. But let me actually take, show you how I would actually take this theme from our markdown document and bring that into my Shiny app.
So, I will take those arguments, try to get multiple cursors here, change these colons to equal, make sure I have commas at the end. Base font, remember, requires a special font Google function. I'm going to do that for the base font and the heading font. And now I should be able to run that and have the same sort of theme look to, something went wrong here. Forgot a comma. Wonder how much my life has been wasted on that problem.
So, yeah, now we got the new different fonts in there. And, again, like the nav bar background color is another sort of like mixture between this darkest black background color that is going to be used for the body and the foreground color that's used for the text.
So, and these are just warnings that I actually don't have like the best contrast ratio. And this is something that this is kind of like a side thing that I think more advanced Shiny developers might want to know about that more recently we've added a function in Shiny called dev mode where we kind of set at least a handful of different options for you that are convenient for developing Shiny applications. So, I actually have this set of my R profile and this is a warning that I will only get in development mode that, you know, obviously we don't always want to be throwing these warnings when you're like running this Shiny app in production.
So, it's something we just like if we have warnings or other things that we think only developers should see, that's something we'll only emit when you have this dev mode set and to set it all you need to do is call that function.
Advanced theming with Sass variables
All right. But let's do a little bit more here. As I mentioned, like this BS theme, we really only have like 10 or 15 different arguments documented here, the bootstrap version, a boot swatch theme if you want one, and then like the more like main color and font settings. But if you want to get more targeted with your theming, hopefully we have a link here.
Not a great link. We could probably provide a better link here to this article on the BSLib websites. You'll find this dropdown has both Bootstrap 5 and Bootstrap 4 SAS variables. And this is a big interactive table with hundreds of different theme settings for customizing lots of different things that go into Bootstrap.
Just know like if you're new to Bootstrap, there's a lot more here than you probably even want to know about because there are like certain components that Bootstrap makes available that we at least currently don't make that available, super available to you in Shiny. So there are things like, just give you a couple examples, like in Bootstrap itself, there are some components like accordions and like alert boxes and carousels, some different components that we don't like provide like official R wrappers for in Shiny package. But, you know, some extension packages make this stuff available. There's like a BS plus package that has wrapped some of these components.
And some other projects out there. But, you know, you can also use those things more directly by essentially like taking this HTML to implement a carousel and writing that in R yourself. So if you actually wanted to do something like that, just to quickly show you. You could basically copy that HTML over and say, I want this div with an ID of this and a class of this and a data BS right of that.
So there is an actual R API that like Shiny provides to you to like write that same HTML as R code and include that in your Shiny app. And lots of people do that, like write custom HTML. So like it would be possible to just like write the same HTML and get a carousel. But I'm not going to actually go through like a real example of that. But just to kind of point out, like there's a whole lot of like stuff that Bootstrap exposes to you. And that's why there's hundreds of different SAS variables is.
Because if you search this table here for something like an accordion, there's settings for like setting the padding on the accordion, like the background color, the border width, like pretty much every single little small detail that would make sense to have like a high level control for. They'll provide it to you through this SAS variable theming interface.
So not only that, we've actually done some work to like make some common things a bit easier for Shiny app developers. So one thing in particular is like this nav bar background color is not an actual like Bootstrap thing, but we've just added it to make your life easier. Where if you wanted to take this basic nav bar page and instead of let me just refresh our memory here and point out like this kind of 50% gray essentially being used for the background of this nav bar. I could set this nav bar dash BG to purple. Now I have a purple background for my nav bar.
And not only that, but bslib will do some extra work to like make sure that you get a sensible contrast by default. So if you wanted like a light blue instead, notice how on this more darker purple, you get a light foreground color to contrast that dark color. But now if I do a light color on the nav bar, it's flipped the text color to dark instead of light.


