Creating responsive light and dark mode experiences across web applications has historically required duplicating design token declarations inside @media (prefers-color-scheme: dark) blocks or maintaining custom CSS class toggles on the root element. The CSS Color Module Level 5 introduced the light-dark() function, allowing designers to declare both light and dark colour values within a single CSS property declaration. The rendering engine resolves the active colour based on the computed value of the element’s color-scheme property. In Safari (WebKit), developers can inspect, simulate, and debug light-dark() colour resolutions in real time using Safari Web Inspector’s dedicated Styles and Computed panels.
Understanding How the CSS light-dark() Function Operates
The light-dark() function takes two arguments: the first colour is applied when the computed colour scheme is light, and the second colour is applied when the computed colour scheme is dark:
/* Syntax: light-dark(<light-color>, <dark-color>) */
background-color: light-dark(#ffffff, #121212);
color: light-dark(#1f2937, #f9fafb);
Crucially, light-dark() is strictly dependent on the element having an explicit or inherited color-scheme declaration. If color-scheme: light dark is not declared on the root (:root or html) or the ancestor element, Safari’s rendering engine does not know the element supports dark mode and will default solely to the light colour argument regardless of the system theme.
Configuring Document Colour Schemes for light-dark() Support
To enable light-dark() across your web layout, you must inform WebKit that the document supports both colour schemes:
:root {
/* Inform the browser that the page adapts to both light and dark operating system modes */
color-scheme: light dark;
/* Declare modern semantic design tokens */
--surface-primary: light-dark(#ffffff, #18181b);
--surface-secondary: light-dark(#f4f4f5, #27272a);
--text-primary: light-dark(#09090b, #fafafa);
--text-muted: light-dark(#71717a, #a1a1aa);
--border-subtle: light-dark(#e4e4e7, #3f3f46);
--accent-action: light-dark(#2563eb, #60a5fa);
}
body {
background-color: var(--surface-primary);
color: var(--text-primary);
}
Furthermore, color-scheme can be scoped locally to force a dark island within an otherwise light page (or vice versa):
.card-dark-featured {
/* Force dark colour scheme on this specific container and its descendants */
color-scheme: dark;
background-color: var(--surface-secondary);
border: 1px solid var(--border-subtle);
}
Simulating System Appearance in Safari Web Inspector
To test how Safari evaluates light-dark() without changing macOS system preferences:
- Open Safari on macOS and load your web application.
- Press Option + Command + I to open Safari Web Inspector.
- In the Web Inspector toolbar, locate the device and rendering simulation controls (or open the Elements tab).
- Locate the Emulate Appearance toggle button (represented by a split sun and moon icon).
- Click the icon to cycle between Light, Dark, and Default (System) modes.
- Watch the live DOM render: all properties governed by
light-dark()transition dynamically between their light and dark arguments.
Inspecting Computed Colour Values in the Styles Pane
When debugging why a colour is not displaying as expected:
- In the Elements tab, select the target element in the DOM tree.
- In the right-hand sidebar, open the Styles panel.
- Safari Web Inspector displays the original
light-dark()declaration. In modern WebKit, the active colour argument is highlighted, while the inactive colour argument is dimmed or indicated. - Click the Computed tab to view the final resolved sRGB or Display P3 colour hex/RGB values after browser resolution.
- If the dark colour fails to render even when Dark Appearance is emulated, inspect the Computed tab for the
color-schemeproperty on that element. Ifcolor-schemeevaluates tonormalorlight, the element has not inherited the necessarycolor-scheme: light darkdefinition.
Debugging Colour Contrast and Gamut in Safari
Safari Web Inspector includes an interactive colour picker and accessibility contrast auditor:
- In the Styles panel, click the colour swatch next to either colour value inside the
light-dark()declaration. - The WebKit Colour Picker opens, displaying current luminance, colour formats (HEX, RGB, HSL, OKLCH), and the WCAG Accessibility Contrast Ratio relative to the element’s background.
- Toggle between Light and Dark emulation to ensure that both colour arguments satisfy WCAG AA (4.5:1 for normal text) or WCAG AAA standards in their respective modes.
Auditing Local Scoped Overrides and Nested Schemes
When mixing light and dark components on a single canvas, verify inheritance cascading in Safari:
/* Light page containing an inverted dark sidebar */
.sidebar {
color-scheme: dark;
background-color: var(--surface-primary); /* Resolves to #18181b */
color: var(--text-primary); /* Resolves to #fafafa */
}
.main-content {
color-scheme: light;
background-color: var(--surface-primary); /* Resolves to #ffffff */
color: var(--text-primary); /* Resolves to #09090b */
}
By inspecting the DOM tree in Safari Web Inspector, you can confirm that descendants within .sidebar automatically inherit color-scheme: dark and resolve the second argument of any light-dark() token, while .main-content resolves the first.
Adopting light-dark() alongside Safari Web Inspector’s theme simulation tools streamlines responsive colour architecture, cuts stylesheet verbosity, and delivers robust, accessible visual themes across Apple platforms.