You open example.com on a phone that prefers dark mode. The page was authored as light, with no color-scheme in the head or the first CSS. In the Safari 27.3 beta, with Adaptive Dark Mode turned on, Safari can repaint that light page as dark: colors and light gradients change, some SVG images and simple logos recolor, and some masks or blend effects can be turned off. Scripts that read the page's colors still get the authored values. The page never told the browser which schemes it supports.
Web HIG tip #17 (Quick #64): Dark mode must re-verify contrast for every semantic token combination used. Declare supported color schemes in the document head or the initial CSS, before JavaScript. light dark is the usual declaration when both schemes are supported. light only is a narrow opt-out, not the default.
Why it matters
A missing declaration leaves the browser free to invent an appearance you did not author:
- Safari Adaptive Dark Mode may transform a light page that does not declare schemes. Canvas stays as authored; CSS colors, gradients, and some images may not
- Script and computed styles keep the authored values, so the repaint is invisible to ordinary CSS checks and many automated contrast tools
- Text, focus, hover, SVG logos, transparent images, and canvas can look wrong while a lab check still reports the authored contrast
- A declaration added by JavaScript later still takes effect, but the first render may already have used the browser's default light canvas and controls. That is the flash you're trying to avoid. WebKit advises against waiting to inject it with script
The full HIG covers this in §3.1, Supported color schemes: pages that support light and dark appearances MUST declare those schemes in the initial document, before any JavaScript runs. In practice, that means the browser knows the schemes before it first renders the page. Quick #64 is Quick-only guidance (no rule ID of its own). The same section states that Safari's contrast aim after a transformation is not a substitute for checking the authored interface in each supported scheme, including focus, hover, and non-text UI.
Before and after
This page has light and dark styles in /styles.css but never declares its schemes. The browser keeps its own canvas, form controls and scrollbars on light defaults, and Safari's Adaptive Dark Mode has to analyse the page instead of being told:
<!DOCTYPE html> <html lang="en"> <head> <title>Orders — example.com</title> <link rel="stylesheet" href="/styles.css"> </head> <body> <h1>Orders</h1> </body> </html> Declare both schemes up front, in markup, in first-paint CSS, or both:
<!DOCTYPE html> <html lang="en"> <head> <meta name="color-scheme" content="light dark"> <title>Orders — example.com</title> <style> :root { color-scheme: light dark; } </style> <link rel="stylesheet" href="/styles.css"> </head> <body> <h1>Orders</h1> </body> </html> light dark tells supporting browsers, including Safari Adaptive Dark Mode, that both appearances are intentional. Only declare dark when you ship an authored dark appearance (prefers-color-scheme, light-dark() or an explicit theme). Otherwise the browser's dark canvas, form controls and system colors can clash with colors you authored for light. Then re-check contrast in that appearance. This snippet does not ship a theme switcher, token files, or a full dark palette.
Do this instead
- Put
<meta name="color-scheme" content="light dark">in the document head, and/orcolor-scheme: light darkon:root(WebKit also acceptsbody) in CSS that applies on first paint, such as a<style>in the head, so the browser has it before the first render and before any theme script runs. Only the root element's scheme sets the page canvas, so prefer:root - Use
light darkwhen you support both. Uselight only(and the matching meta value) only when a surface must stay light; it is a narrow opt-out, not the default - Do not rely on
light onlyas an opt-out until you've confirmed it works in each browser in your matrix. Browsers have parsedonlyfor years, and MDN notes Chrome's Auto Dark Theme respects it. But WebKit says Safari 27.3 beta 1's Adaptive Dark Mode did not support it, so it wasn't a working opt-out there - Re-check contrast for text, focus, hover, and non-text UI in every scheme you declare. Measure authored colors; a browser repaint that computed styles cannot see is not that measurement
- When Safari is in your matrix, keep a visual record (screenshot or equivalent) of Adaptive Dark Mode cases. The HIG requires reviewers to capture these. Automated contrast on computed styles can stay green while the painted page fails
- If the product adds a theme control later, keep the document-level declaration honest about the schemes you actually support
Quick check for your app
Open example.com and a second key page at a phone width. View source or the Accessibility/Elements panel and confirm a color-scheme meta tag or first-paint CSS declaration before any theme script. Toggle the OS appearance and, where you support Safari Adaptive Dark Mode, capture light pages with and without the declaration. Compare authored computed colors with what you see painted. Suitable automated checks can catch a missing declaration and authored contrast regressions; they do not prove how Adaptive Dark Mode paints. Pair them with a visual check on the browsers your audience uses.
The Web HIG is an open set of guidelines for how the web should behave, not a component library. Design systems define how it looks. The Web HIG defines how it behaves.
- GitHub: https://github.com/frozonfreak/webhig/discussions/35
- Hashnode: https://thewebhig.hashnode.dev/declare-supported-color-schemes-web-hig-tip-17
- Dev.to: https://dev.to/frozonfreak/declare-your-color-schemes-before-the-first-paint-web-hig-tip-17-42bl
- Bluesky: https://bsky.app/profile/sastha.bsky.social/post/3n26df6xrt22g
