How to make custom callouts for Quarto

Quarto
Website
CSS
A brief tutorial on implementing callout style layouts in Quarto for those with rudimentary CSS/HTML skills like myself.
Author

Andreas Handel

Published

June 13, 2023

Motivation

I am currently using Quarto for most of my writing. I write papers, make presentations and create websites using it. For a recent website project, I wanted callouts similar to the ones that come with Quarto, but ones that I can customize. Given my limited web coding (HTML/CSS/Javascript/etc.) experience, it took me a bit to figure it out and I had to cobble it together from different sources. I figured others might be interested, so here’s a brief write up.

Introduction

If you are not familiar with Quarto callouts, take a look at this explanation. It’s a nice way to highlight something in text. For instance this bit of code produces one of the pre-built callouts that come with Quarto.

::: {.callout-tip}
## Tip with Title
This is an example of a callout with a title.
:::
Tip with Title

This is an example of a callout with a title.

As the Quarto website explains, some customizations are possible, but it’s limited. I wanted my own boxes with colors and text and icons of my choosing, and that is not - as the time of this writing - a built-in possibility. So I tried to figure out how to do it myself.

Looking for examples

What I wanted was my own callout box, with a look (colors, icon, etc.) that I can adjust. The closest information I could find online was this Stackoverflow question/answer but unfortunately I couldn’t quite get it to work (and I don’t know why).

I remembered this post from Desirée De Leon, and it gave me the overall idea on how to do it, but I wanted a look that was similar to the Quarto callouts.

Then I found this resource which shows how to make a callout box. It didn’t have quite the look I wanted, and had some features I didn’t like/want, such as being able to click it away and placing it in the bottom corner. But between this example and the example from Desirée`s post, it gave me enough to work with.

Making my own

The setup

Quarto uses either CSS or SCSS files for styling. CSS files do the heavy lifting for styling of websites. SCSS files are basically extensions that allow for additional features. This presentation by Sam Csik gives a nice non-technical introduction for CSS/SCSS styling with Quarto. The details aren’t too important and I certainly don’t fully understand CSS/SCSS. For our purpose, we could use CSS but since SCSS seems to be more flexible, and we can stick all CSS into that file, we might as well use that format. Start by creating an empty SCSS file (or find some template online). Let’s assume it’s called customstyle.scss and you placed it in the same folder as your _quarto.yml file. Then add this SCSS to _quarto.yml, e.g. to look like this:

format:
  html:
    theme: 
      light: [matria,customstyle.scss]
      dark: [slate,customstyle.scss]

See here for some more information.

The styling

Now comes the main part, adding instructions to the SCSS file to get the look we want. I’m basically combining bits and pieces from the sources I linked above. All the code below goes into the /*-- scss:rules --*/ section of your SCSS file. I’m naming my callout goals but you can use any name you want.

First we specify the overall box with a rounded border.

.goals {
  margin: 1em 0;
  border: 2px solid gray;
  border-left: 10px solid teal; 
  border-radius: 10px;
}

The next code block sets up the header/title section.

Note that I needed to round the background box in the top right corner so it has the same shape as the overall box/border defined above.

I’m also including a small icon here, following the blog post instructions by Desirée mentioned above. I got the icon from here. Depending on where you place the icon, you will have to adjust the file path inside the url() command.

.goals-header {
  margin-left: 0em;
  padding-left:  60px;
  padding-top:  5px;
  padding-bottom: 0.1em;
  color: black;
  background-color: rgb(123, 173, 173);
  border-top-right-radius: 10px;
  font-size: 1em;
  font-weight: bold;
  background-size: 40px;
  background-repeat: no-repeat;
  background-position: 15px center;
  background-image: url("goal.png");
}

And the last bit of code styles the main text portion of the callout.

.goals-container {
  padding-top: 5px;
  padding-left: 10px;
  color: black;
  background-color: white;
  border-bottom-right-radius: 10px;
}

Using your new callout

This is fairly easy, you are using the same fenced div notation as for the built-in Quarto callouts shown above. The only additional part is that you need to nest them like so:

:::{.goals}
::::{.goals-header}
Learning Goals
::::
::::{.goals-container}
* Know how to make your own callouts.
* Be able to mess with some SCSS/CSS styling.
::::
:::

The nesting is accomplished by giving each level up/down one more/fewer :.

This will produce the following.

Learning Goals

  • Know how to make your own callouts.
  • Be able to mess with some SCSS/CSS styling.

I’m quite happy with this. It looks fairly similar to the Quarto built-in examples. It could use a bit more refinement and adjustment, but I think the overall setup is clear enough that you can take it from here 😁.

Summary

To sum it all up, here is what you need to do:

  1. If needed, create a new SCSS (or CSS) file and add the SCSS/CSS code chunks above to it.
  2. Edit your _quarto.yml file to include your new SCSS file.
  3. Write .qmd documents using the fenced div (:::{}) approach shown above.
  4. Keep adding as many new styles as you want, and adjust them to however style you like.

Further resources

Lots of folks create fancy looking websites and other Quarto documents. I like looking at Andrew Heiss websites for inspiration. He has a nice personal website and also great course websites, all made in Quarto and all out in public. For instance here is the Github repo of his personal website and he has lots of styling going on in his SCSS file inside the html folder. In fact, I checked his materials first to see if he has an example of what I’m looking for, but I didn’t see that one.

CSS powers the styling of the internet, so there are tons of resources out there telling you all the things you can edit. The resource I use above, W3 Schools is useful, but there are many other good resources - Google is your friend. Also, editors like VS Code, which I use to edit these files, have auto-complete, so you can start with say border and it will tell you all the options.

Acknowledgments

As always, I rarely come up with completely new stuff, instead I cobble it together from other resources. The sources I cite above should obviously receive all the credit for the underlying ideas and explanations.