
Quarto Websites 3: Customize appearance with CSS/SCSS | Emil Hvitfeldt | Posit
You now have a set of content you are happy with on your website, but how do you customize the look and feel of your site beyond options set in YAML? In this video, you’ll start by learning the basics of CSS and SCSS and how to make good design choices. Then, you’ll see how to apply these choices to your Quarto website. In this video: 0:14 What is HTML? 3:23 CSS Selectors 8:05 CSS Attributes 8:25 Layout attributes 10:24 Reducing repetition with SASS/SCSS? 15:26 Consistent design 16:36 Choosing colors 17:50 Choosing fonts 19:28 Maintaining accessibility 22:13 Apply SCSS to your website 24:16 Change the appearance of headings 25:28 Change the appearance of navigation bar 30:30 Use google fonts Links: Color contrast checker: https://colourcontrast.cc/ Google fonts: https://fonts.google.com/ Code: Starter source code: https://github.com/cwickham/quarto-website-video/tree/v0.2 Final source code: https://github.com/cwickham/quarto-website-video/tree/v0.3 For more in-depth coverage and slides check out: https://posit-conf-2024.github.io/quarto-websites/ Do you need a professional website to showcase your work? If you’ve used Quarto to produce a document, you’ve already got the technical skills to create a Quarto website. In this video series, you’ll learn everything else you need to build a website and customize its appearance. This video series is for you if you: - Have used Quarto to generate documents (e.g. HTML, PDF, MS Word etc.) - Are comfortable editing plain text documents (e.g .qmd) in your IDE (e.g. RStudio, Visual Studio Code etc.) - Want to walk away with your own personal website Taught by: Charlotte Wickham (https://www.cwick.co.nz/) Emil Hvitfeldt (https://emilhvitfeldt.com/) Videos in this series: 1. Build your homepage [https://youtu.be/l7r24gTEkEY] 2. Add pages and navigation [https://youtu.be/k65E-8PXZmA] 3: Customize appearance with CSS/SCSS [https://youtu.be/pAN2Hiq0XGs] 4: Add lists of content with listings [https://youtu.be/bv_Cw-3HI1Y]
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Alright, welcome back. Now we'll be looking at how we can take our website we've created so far and use CSS and SCSS to further style it to your liking. So before we get going at that, we need to talk very quickly about what HTML is, because that is how all websites are created. And we need to understand how that works to be able to style the different components.
So all HTML is built inside these things called divs, which are having the syntax we see right here with tridivial brackets and the name of the tag inside of it. And we can nest them like we see here as well. And a general website is built around four main tags. So we have the HTML tags, which is the outermost one that contains everything else. And inside of that, we have a head and a body. In the head, we do things like loading style sheets, loading metadata, things we don't really need for the user, and the body contains everything we see. Quarto basically deals with everything that goes into the header. And we just have to focus on what happens in the body.
Some of the common HTML tags we see are these header ones, which we also use in Quarto with the pound sign. So they have to go from one to six. A paragraph is what it says. We also have links, and the general div is just named div. But there's many, many more tags, but these are the most common one we will see. In addition to having a name, they can also have attributes, and they provide more information about what happens. And they all are specified the same way with a name, equal sign, and then some value in it. And this is also the same way we specify classes and IDs.
So to be able to style and use a website programmatically with something like JavaScript, the different elements on the page will have different classes and IDs to be able to mark them as special in different ways. Another type of attribute is the way images are being used. So we have the image tag, and it uses the source attribute to link to the file it needs to showcase.
So we can style our website in two different ways. One of them is styling it inline using attributes. So here we can see we have style equal, and then we set color equal to red. This is fine, but it can be a very long, drawn-out and error-prone process if you start having a more complicated website. And it is often preferred that we use a style sheet that would then be linked in the head, which is what Quarto will do for us if we specify it in the YAML file.
CSS selectors
So the way we use CSS to style these different elements on our page, we need two things. First, we need selectors, so what needs to be styled. This is telling CSS what HTML elements that need to be styled, and then the attributes, which is how they should be styled. So first, we'll talk about the selectors. So we can select something in a couple of different ways, and we can select something by a tag. So here we say, I want to select all the level one headers. We say that by saying H1, and then the curly bracket, which will inside the curly brackets, will denote how it should be styled. We can also specify something by class. That is done by putting a period before the class name. And lastly, we can talk about selecting something with an ID, and we use the pound sign before the ID name.
By itself, this isn't super useful, so we need to be able to combine them in different ways. So one of the first ways of combining is doing an AND combination. So if we say H1 comma H2, then every style we apply inside these curly brackets will be applied to all of H1 headers and all of H2 headers.
So a handy little thing I end up doing a lot is setting up this selector that selects all headers from level one through level six. Another selector is being able to select deeply. So if we say p space span, we are selecting all span elements that are somehow inside a p element.
So here we see that here we have a span right here, but it's just a span by itself, so it doesn't do anything. But we also have a p paragraph right here, and it has a span inside. So the above selector will only select this span inside the p. A more specific one is using this greater than symbol to be able to only select one level deep. Since we can nest all these elements, there will be a hierarchy in it, and we think of things that are just inside as being one level deep, and then if you're one more level in, you're two levels deep, and so on.
And a lot of websites can be very complicated with a lot of nesting, so sometimes it's useful to just say, I want to select everything that's just one level deep, and for that we use this greater than. So here we see I'm selecting happy, so we're selecting this the outermost div right here that has the class happy, and only selecting the H2 one level deep would be this first one, because the second one is two levels deep, so it wouldn't be selected. We can also do combinations, so we can say if we don't put a space between things, then we are saying and in a different way by saying all H2 elements with the class. So we can specify something jointly by having the same class and a tag, and this way we can also select multiple classes in a row, because the period, we just add another period something, period something at the end.
There's many more things we can do. One other type of select I want to showcase is the pseudo classes that modifies existing classes in different ways, and one you will see a lot is the hover and active one. So the hover pseudo class changes the style of something that is being hovered, so when you have the mouse over it, it will apply the style we see specified in here, and active we can see that if we have a menu or a nav bar where we are on a specific page, we can say whatever page we're on right now should be styled differently than the rest.
And then part of the name of CSS is the cascading, and that is a very long way of saying that if we specify multiple rules that select the same element, there is a rule set that you can find online if you search for it that specifies who wins. It's quite complicated, but the general rule is that a more specific selection wins to a less specific selection. So if you have a rule for h1 and a rule for h1 title class, the h1 title class will win because it uses a tag and a class which is more specific than just a tag.
CSS attributes
Now that we've found out how to select different classes, we can also look at how we can change things, and we can change things by how they look or how they're positioned from each other. And things how look is things like color sizes, and colors can both be text color, border color, background color, all different things. So the general layout model we use in HTML is that each element on a page has a content area here you see in blue, and then it has a border. So border goes all the way around it. A lot of the times it's invisible, but it's still there. Then there's a padding, which is the spacing from the border to the content. So it's like the inside spacing, and we have the margin, which is the outside spacing as well.
The content is specified using length or percentages, and there's many, many different ways of specifying length in CSS. So we can either specify by pixels or by any other unit we have, or we can do things like percentages whenever it makes sense. So sometimes we can say, I want the width to be 50% of the width, and it will take up half of its parent's width.
Padding, which is the spacing between the content and its border, can be specified in two different ways. So we can either specify it once using the padding attribute or specifying with the four more specific attributes, which is padding, bottom, left, right, and top. These are also lengths and percentages. It works in a couple different ways, but the main thing is if you want all the four values to be the same, we can use padding as the value here, and it just works all the way out.
And if you want to be more specific, we can specify the four values independently. The border works in pretty much the same way, but instead of having top, bottom, left, and right, it has color, style, and width. So we can specify them at once, or we can specify them one at a time. And margin works just as padding did.
Reducing repetition with SCSS
Now that we saw what CSS is, you might be wondering why we're also been talking about SCSS. So SCSS, I find very useful because it's an extension of CSS. It's very useful for the types of websites that we end up creating when we work with Quarto. And Quarto have native support with SCSS. So why do we use it? The first and main reason is it's CSS compatible. So just because you have a SCSS file in your product doesn't mean you actually need to use it. You can just use plain CSS, which we actually will be seeing more of later. But it has a lot of features that just elevate our day-to-day use with CSS quite a lot. And it's quite mature, so there's very few breaking changes over time. It's a fairly stable product. And you can kind of think of it as CSS, but with variables, nested rules, and functions. The way it works is you have your SCSS file, and it will compile and generate a CSS file, which a browser will understand.
You can kind of think of it as CSS, but with variables, nested rules, and functions.
So when you push up your website, you don't actually push up the SCSS file. It will be a generated file. But Quarto will do all of this for you, so you don't have to worry about it. So we have things like SCSS variables. So much like we have in Python, we're able to store value in a variable and then use it later. And this is very nice to be able to reduce repetition. And the syntax is dollar sign, variable name, and then colon, and then what value we want. I end up using it a lot for colors, so we can specify our color theme at the beginning and then use it throughout.
We also have the idea of nested rules. If you have a website where you need to style a lot of things, you end up writing quite a lot of different rules to specify different things, but some of them are connected by what they do. So here we have like the h1 or h2 header, and we want to have a specific color, but we want any links inside of it to have a different color. So we could specify it on the right by two different rules, but we could also specify it on the left, which is the CSS nested rules. So anytime you specify something inside another thing, it knows that it uses both. For this example, it isn't a lot, but it ends up becoming very useful long-term, because it forces you to keep things that are related close to each other in the code.
And it also works with the selectors combination. So you can also say here we use the greater than symbol inside our nested rule, and it just works. And it just adds a native organization. So here I have a speech class I created for a different project, and it uses nested rules. And it means that every single thing right here, I know that since it's inside this speech class, I know they're all related. And the IDE I'm using knows that they're all related, and I can collapse and work around with it in a very pleasing way.
There's also the idea of mixins. And that's another way of reducing repetition. So we know that we need to apply the same attributes to a lot of different selectors. We could use the idea of a mixin. So we specify mixin. Here I told padding small. And we can include it under a lot of different selectors. And it essentially just copy pastes the values in. And you see, and this is not like a make it or break it feature. But what it does is, once you see attributes for it, you really love it. Oh, this makes perfect sense. I'm going to use it right here, save a little bit of real estate.
And we also have functions. So there's a lot of functions to talk about. The main ones I end up using is the color modification functions. So we tend to darken a color or lighten a color. But there's also much more expansive, you can do math, there's a conditional logic you can use in this. Plus it all compiles before it goes up on the website. But here is an example that I use a lot where I specify a few number of colors at the beginning. And then I can slightly modify them. So I have different colors of blue, but they're all derivatives of our main one color. And if we decide this color isn't actually modified a little bit, all the changes propagate through the entire style sheet.
Consistent design
All right, so we learned about how to actually make the styling happening. But we also need to think about the content on the slides and the different websites we have. And a very important thing is to have a consistent design. So the way most people work when they look at a thing, we see and look for similarities and differences whenever we see a page or something else, and we'll pick up when something is different. You will assign value on differently styled elements. And we can use this for good or for bad. So if we're very conscious about how we style everything, we can direct the user's attention to the parts of the website we want them to take their attention to. But if we have passively styled the website, we might accidentally draw attention to a section that didn't need to be drawn attention to.
If you follow the CSS paradigm of the way we style things, this won't be an issue as much, because the styling pretty much just happens all the way around.
Choosing colors
We can choose colors. There's three main places you can do it. You can either be forced into a color scheme that will use some guidelines you can find. And that's just finding it in your internal documentations and pull out the colors you try to use. You can pick them yourself. And a thing I'll end up doing is on Pinterest and search something, something color palette. And there's a lot of different inspiration online. Once we've selected the color we want, I like to create a color palette.
So the way I create it is I do it as a set of variables, and all the variables are prefetched with theme dash. This way I know what they are when I use them, and I give them very human readable names. So it might be a very specific shade of blue, but I just call it blue. And if there's multiple blues, you need a light blue, and a blue, and a dark blue, or something like that. But you shouldn't be too specific, because it's the general idea of blue you're using here. And then we can use it throughout with the light and dark function if we need some slight variations of it.
Choosing fonts
And then the way we choose fonts is to keep accessibility in mind, and maybe the readable font. There's a lot of very fun, handwritten fonts that might look really nice on a wedding invitation or other artistic purposes, but wouldn't be good for general text in our website. And it's not as exciting of an advice, but commonly used fonts are by definition readable, because they're familiar.
So using a font that everybody uses gives you the benefit that people are used to it. But you also need to take into account that some fonts are designed to be used in different places. So fonts that might work really well on print might not work as well on the web, or very old. There are some old fonts that were designed for typewriters, because of the way typewriters worked, but are solving for problems that we don't have anymore in our digital media.
And then another sad advice is to don't pick too many. Because if you start picking too many fonts for a project, it starts taking away or tries to indicate importance on the website. So pick a couple of colors. You generally want a header font, a normal text font, and a quote font. And you can maybe do one more, but you want to keep it at a very reasonable amount.
Maintaining accessibility
And then lastly, we want to make sure we maintain accessibility. The long and short of it is you want your website to be seen by people. So it's against your best interests to make it so some subset of the population have a hard time accessing your website. And this can be via disability or other impairment, but you should want it to be visible to as many people as possible. Other types of things we can do, we can avoid blinking and flashing content, because you most likely don't need it. You can maintain high color contrast. Right here, we have dark text on a white background. If we make the text lighter, at one point, it becomes really hard to see. We can add all text to non-text elements, such as pictures or drafts, to make sure that people on screen readers can see them as well. Another thing we can do is ensure auto-complete functionality via the keyboard.
So if you do, I want to say it's there. So on my Mac, I can do Option-Tab, and it will go through the links on this website right here. So it first goes to the first link, and if you do one more time, it goes to the hamburger menu at the bottom left. So if you go here and click Enter, you can navigate the website without ever using the mouse. So that's another accessibility.
And this likely also showed us one of my favorite color contrast chapters. So we can see right here, we have a background color and a foreground color. If I change the background color, move the saturation down, and we see a number. So when the number is high, we have a bit contrast. When the number goes down, we have lower contrast. And as we move the lighting down, we get some small numbers, and we see on the right-hand side that some of these values fail. So we see here, we can pass them all just when we hit seven.
So the color contrast we need to ensure accessibility will depend on the size of the text. So large text can manage a low contrast, where small text need a bit contrast. But in general, you should make this as high as possible without messing with your overall design.
Applying SCSS to your website
All right, now we're back at the website we've been working on so far, and we're going to try to apply what we learned to our style sheet. So here we have the Quarto.yml file that has everything we need, and we also have our styles.css file. So before we move on, we noted that we have some styling happening down here below. So we specified some things directly in the HTML, and we're going to try to undo some of those. So I'm going to take away this line right here, and it will undo some of the styling we saw.
And I'm going to re-implement it right in here. So I'm going to just paste them in here so we can see them. And I want to use the technique I showed earlier about creating a color palette. So at the beginning, I will create this color palette by using the theme-naming convention. So I'm reusing the light green, green, and black that we saw down here, and now we need to apply them. So we already have the SCSS variable set up right here under colors. We just need to use them. So the body background right here, this theme light green, this is partly why we use the names because auto-completion works really well. The body color was theme green, and the link color right here is a very standard theme black. And it complains because this isn't valid. But if we save, now we have the same styling as before, but using SCSS instead of the options we set in the YAML file.
So another thing we can do is to start trying to do some things. So let's try to change the header. So the way I normally do things is just by saying color red because it really shows up. And here we see on the website to the right, that changes this header. Here's the first name, but it doesn't change the other one. You can set in the other one by saying also do h2. And for the measure, we just add all the headers. But we probably don't want it red. We probably want it to be theme green, which it technically already is right now. But now it's doubly verified.
But we can do another thing. We can say attached transformation, and we can say uppercase. So that means that all the headers now will automatically be uppercase regardless of what it was before. And we'd also force it to be lowercase or like title case.
But I think this is good for now. We've noticed up here we have the header, and the header isn't styled. And when we hover over it, it just has like a black color. So maybe we don't want that. So first, we just need to find it. The way we find it is we open up right here, and then we can right-click and inspect. And it brings up this little developer menu. And with this little button up here, we can select an element. So here, by moving around, it selects different things. So let's try to select the Charlotte one. And now we can see the HTML of everything it has on the right-hand side. And we notice that if we go up here in the hierarchy, that everything is in this nav bar that selects everything up here. So now we have the nav bar.
We can look back down, and we say everything with the nav bar class should have the color. And update it, but nothing happened. And the reason why is because we're only changing the color of the text in the nav bar element, but we actually want it in the children. And another selector we have is the star sign, which basically means everything. So here, we are selecting all the children in the nav bar and changing the color. And we don't want it to be green, so we say theme green. And now the text and icons in the nav have been changed.
But maybe we want to change the header, the name up here a little bit differently. So if we go back, now we're back to the website. We can select this element up here, and we see there's a span with the class nav bar title. So we go back to the editor, and we can say span nav bar title. We do the thing where it colored red at first to see what happens. We select the red thing. And so that is fine. So now we know that we selected it, but we actually want to select, maybe do a little hover thing. So we say the total on hover, and we say color equal to red. So it should keep its color because it's specified by everything. But when we hover over it, it turns red. But the way it does it is like, oh, it's red, now it's green. So what we can do to change this is the transition duration, and we can set it to like two seconds.
So now that we hover over it, it changes into red over two seconds, which is a little much. So let's do maybe 0.5 seconds. So it quickly snaps in. But if you notice, it automatically goes back. So its normal styling should also have a transition duration. So now it transitions.
It didn't transition both ways, but that's fine, because we can do it a different way. So this is where the nesting becomes useful. So now we create a nested rule right here. So now we need one more here. All right. So now that we have these nested rules, here's what we have. We are styling the title by itself, giving it a duration. We're also styling its hover with a different color and a duration. So now when we hover over it, we repeat the color. Now it has a color both ways. But the color it has inside isn't really that great, because it's red. We want it to be a little bit interesting. So we can say lighting and theme green. And I want to say it should be lighter by 10%. So now when we hover over it, it changes to a slightly lighter green. So it shows that we have it. So we have some tactile effects on our website that shows, hey, I'm looking at what you're seeing.
Choosing fonts for the website
If we go back to the website, we might want to pick out some different fonts. So the way we go that I do is go to fonts.google and look around to see what we have. And there's a bunch of different ways we can filter everything out. I kind of like this new Poppins one. It probably isn't new, but it was new to me. And we can see the different weights. And you can change the text. You want to preview in different ways. But you say, I like this one right here. I'll edit. You click that font. And then you click up here in embed code. And we'll press import and copy this in. So we go back at the very top. And I accidentally had another thing. So we just take whatever in it says, put it here at the top. And then going back one more time, the font family here is called Poppins. So we can replace it right here. Font family, Poppins. Oh, and we're overwritten by the main font specified in the YAML. And now we're using our differently specified font.
And all right, that's everything I have to show right here. There's this general idea of how we can go around changing things. It's a lot of trial and error. So you end up in the inspection mode, seeing what happens, what everything's called. You don't always get the cascading rules right the first time. But you learn as with everything we try to do.


