In Quarto, it is possible to set a switch for display, which shows a switch button to control the theme of the website:
_quarto.yml
:
project:
type: website
format:
html:
theme:
light: flatly
dark: darkly
I'd like to include a gt
table that changes its theme according to the Quarto settings. Given the default example from gt
:
Example page.qmd
:
---
title: "Example page"
format: html
---
```{r}
library(gt)
# Define the start and end dates for the data range
start_date <- "2010-06-07"
end_date <- "2010-06-14"
# Create a gt table based on preprocessed
# `sp500` table data
sp500 |>
dplyr::filter(date >= start_date & date <= end_date) |>
dplyr::select(-adj_close) |>
gt() |>
tab_header(
title = "S&P 500",
subtitle = glue::glue("{start_date} to {end_date}")
) |>
fmt_currency() |>
fmt_date(columns = date, date_style = "wd_m_day_year") |>
fmt_number(columns = volume, suffixing = TRUE)
```
When the theme is flatly
, it looks fine:
But when the theme switches to darkly
, only the code responds to dark mode, not the table:
I am just wondering how to make the table react to the Quarto theme?
Change the background-color
of the table to var(--bs-table-bg)
and set color
to inherit
:
This is implemented below by modifying the table's css.
However, for better readability and in order to keep the striped layout, it is maybe beneficial to make further adjustments: I implemented an Event listener which toggles the Bootstrap classes table-light
and table-dark
on the gt table depending on the dark mode state.
---
title: "Example page"
format:
html:
theme:
light: flatly
dark: darkly
include-before-body:
text: |
<script>
document.addEventListener("DOMContentLoaded", function() {
const attrObserver = new MutationObserver((mutations) => {
mutations.forEach(mu => {
if (mu.type !== "attributes" && mu.attributeName !== "class") return;
var gt_tables = document.getElementsByClassName("gt_table");
var table_array = [...gt_tables];
table_array.forEach(tbl => {
if (document.body.classList.contains("quarto-light")) {
tbl.classList.remove("table-dark");
tbl.classList.add("table-light");
} else {
tbl.classList.remove("table-light");
tbl.classList.add("table-dark");
}
});
});
});
let targetNode = document.querySelectorAll("body");
targetNode.forEach(el => attrObserver.observe(el, {attributes: true}));
});
</script>
---
```{r echo = FALSE}
library(gt)
modify_css <- function(x) {
x <- gsub(
"background-color: #FFFFFF;",
"background-color: var(--bs-table-bg);",
x)
x <- gsub(
"color: #333333;",
"color: inherit;",
x)
htmltools::HTML(x)
}
# Define the start and end dates for the data range
start_date <- "2010-06-07"
end_date <- "2010-06-14"
# Create a gt table based on preprocessed
# `sp500` table data
sp500 |>
dplyr::filter(date >= start_date & date <= end_date) |>
dplyr::select(-adj_close) |>
gt() |>
tab_header(
title = "S&P 500",
subtitle = glue::glue("{start_date} to {end_date}")
) |>
fmt_currency() |>
fmt_date(columns = date, date_style = "wd_m_day_year") |>
fmt_number(columns = volume, suffixing = TRUE) |>
as_raw_html() |>
modify_css()
```