Working with Dark Mode

Adapting content for the user’s preferred visual theme.

All modern operating systems, including Android, iOS, macOS and Windows, now allow users to adjust their UI to appear in a light or dark visual theme. This can be based on ambient lighting conditions, a daily schedule, or the user’s preference at the moment. It can also extend to the content of apps and webpages on their device.

We strive to respect this on the same level as the user’s choice of device or text size. Below are some tools and tips to help speed development and automate support.

Adaptive Colors

Pages have some built-in colors that adapt based on light/dark mode. Using these for common elements are recommended for consistency and because you get dark mode support out of the box.

Elements CSS Variable Color in light mode Color in dark mode
Page background var(--color-bg) var(--white) / #ffffff var(--cool-90) / #1b2127
Headline var(--color-text-hed) var(--black) / #000000 var(--gray-10) / #e2e2e2
Body text var(--color-text-body) var(--gray-90) / #1b1b1b var(--gray-20) / #c6c6c6
Caption var(--color-text-supp) var(--gray-70) / #474747 var(--gray-40) / #919191
Credits var(--color-text-meta) var(--gray-40) / #919191 var(--gray-60) / #5e5e5e
Buttons, links var(--color-accent-10) to var(--color-accent-90) the current page’s accent color, 1090 the current page’s accent color, reversed, so 9010

Common Workarounds

Hiding/Showing in Dark Mode

There are some helper classes for hiding and showing elements:

These are useful if you have made two different images to show per mode.

Selectors for Dark Mode Styling

/* Styling aimed at light mode */

html.force-light-mode [SELECTOR] {
    [STYLES]
}
@media (prefers-color-scheme: light) {
    html:not(.force-dark-mode) [SELECTOR] {
        [STYLES]
    }
}
/* Styling aimed at dark mode */

html.force-dark-mode [SELECTOR] {
    [STYLES]
}
@media (prefers-color-scheme: dark) {
    html:not(.force-light-mode) [SELECTOR] {
        [STYLES]
    }
}

Forcing a White Background on iframes

In some cases, you may not be able to style something for dark mode. For example, iframes are isolated from any custom css, and if it has a transparent background it may be unreadable in dark mode. (Older Datawrapper embeds need this, but newer ones should not!)

To work around this, give it a white background and some padding:

html.force-dark-mode [IFRAME SELECTOR] {
    background-color: var(--white);
    padding: var(--spacing0);
}
@media (prefers-color-scheme: dark) {
    html:not(.force-light-mode) [IFRAME SELECTOR] {
        background-color: var(--white);
        padding: var(--spacing0);
    }
}

Setting a Black Page Background

There are situations where the editorial design calls for a black background with light text, e.g. photo essays. This snippet can be used for readers who have not explicitly expressed a preference for light mode. If they have, they will continue to see dark text on a white background.

<script>
document.documentElement.classList.add("force-dark-mode");
</script>

<style>
.force-dark-mode body { background-color: var(--black); }
</style>