Merging @media prefers-color-scheme
and Quarto Dark Theme Toggle
#2588
cadojo
started this conversation in
Feature Requests
Replies: 3 comments 7 replies
-
I would love this feature too! |
Beta Was this translation helpful? Give feedback.
0 replies
-
Furo has a model that I like a lot: Toggle between system preference (default), light theme and dark. This makes sense to me as the default behavior whenever both light and dark themes are specified. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Hey all, I figured out a way to do this. This code does two things:
Quarto configformat:
html:
theme:
light: flatly
dark: darkly
css: styles.css
toc: true
include-in-header:
- toggle.js toggle.js<script id="toggle-light-dark-elements" type="application/javascript">
// Extend Quarto theme toggling to allow elements to be displayed/hidden in light/dark themes
// Replicated from https://github.com/quarto-dev/quarto-cli/blob/84d4659/src/resources/formats/html/templates/quarto-html.ejs
const getColorSchemeSentinel = () => {
const localAlternateSentinel = 'default';
if (window.location.protocol !== 'file:') {
const storageValue = window.localStorage.getItem('quarto-color-scheme');
return storageValue != null ? storageValue : localAlternateSentinel;
} else {
return localAlternateSentinel;
}
};
// Function to toggle light and dark elements based on color scheme
const toggleColorSchemeElements = () => {
const scheme = getColorSchemeSentinel();
const lightElements = document.getElementsByClassName('only-light');
const darkElements = document.getElementsByClassName('only-dark');
for (var i = 0; i < lightElements.length; i++) {
lightElements[i].style.display = scheme == 'default' ? 'block' : 'none';
}
for (var i = 0; i < darkElements.length; i++) {
darkElements[i].style.display = scheme == 'default' ? 'none' : 'block';
}
};
// Function to check if the user's browser prefers dark themes
const prefersDarkTheme = () => {
if (window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return false;
};
document.addEventListener('readystatechange', function() {
// Set the default color scheme based on browser preference
if (document.readyState === 'interactive' && window.location.protocol !== 'file:') {
const storageValue = window.localStorage.getItem('quarto-color-scheme');
if (storageValue == null && prefersDarkTheme()) {
window.localStorage.setItem('quarto-color-scheme', 'alternate');
}
}
// Add event listener for when the readyState is complete (and default toggler is set)
if (document.readyState === 'complete') {
// Toggle scheme once
toggleColorSchemeElements();
// Append our toggle function to the old one
const oldToggle = window.quartoToggleColorScheme;
window.quartoToggleColorScheme = () => {
oldToggle();
toggleColorSchemeElements();
}
}
});
</script> |
Beta Was this translation helpful? Give feedback.
7 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I like having the light / dark theme toggle that Quarto provides, but it's also nice for the website to default to whatever the system's default is. Ideally, I'd like to set the Quarto toggle to only have "memory" for the last 6 hours or so, and otherwise default to the system default using
@media prefers-scolor-scheme
. Has anyone figured out how to do this?Beta Was this translation helpful? Give feedback.
All reactions