Developing a Design Adaptation for prefers-color-scheme in 1C-Bitrix
prefers-color-scheme is a CSS media query that detects whether the user has selected a dark theme in their OS settings. It is supported by all modern browsers. The goal: a Bitrix site should render in either dark or light mode based on the user's system preferences — without a manual toggle, or alongside one.
Approaches to Implementing a Dark Theme
Approach 1: Pure CSS variables. All site colors are defined as CSS custom properties. Under prefers-color-scheme: dark, the variables are overridden.
:root {
--color-bg: #ffffff;
--color-text: #1a1a1a;
--color-surface: #f5f5f5;
--color-border: #e0e0e0;
--color-primary: #0066cc;
--color-primary-text: #ffffff;
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #121212;
--color-text: #e8e8e8;
--color-surface: #1e1e1e;
--color-border: #333333;
--color-primary: #4d9fff;
--color-primary-text: #000000;
}
}
All template CSS uses only variables — no hardcoded values. This is the cleanest approach, but requires refactoring existing styles.
Approach 2: dark CSS class on <html>. Dark styles are activated by a class:
html.dark {
--color-bg: #121212;
/* ... */
}
JavaScript toggles the class based on system settings and the user's explicit preference (saved in localStorage):
(function() {
const savedTheme = localStorage.getItem('theme');
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const isDark = savedTheme ? savedTheme === 'dark' : systemDark;
if (isDark) document.documentElement.classList.add('dark');
// Listen for system theme changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) { // Only if no manual choice has been made
document.documentElement.classList.toggle('dark', e.matches);
}
});
})();
This script must run synchronously in <head> before the DOM renders, otherwise there will be a flash of wrong theme (FOWT).
In Bitrix, add this to the site template's header.php before </head>:
<script>
<?php
// Inline the minified theme initialization script
echo file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/local/js/theme-init.min.js');
?>
</script>
Theme Toggle in the Interface
A button in the site header allows manual theme switching, overriding the system preference:
document.getElementById('theme-toggle').addEventListener('click', function() {
const isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
this.setAttribute('aria-label', isDark ? 'Light theme' : 'Dark theme');
});
The button icon changes via CSS variables or a pseudo-element with different content depending on the class.
Handling Images
For logos and icons that look poor on a dark background, use the HTML <picture> tag with the media attribute:
<picture>
<source srcset="/img/logo-dark.svg" media="(prefers-color-scheme: dark)">
<img src="/img/logo-light.svg" alt="Logo" id="site-logo">
</picture>
With a manual toggle — JavaScript updates the src attribute of the <img> element.
Product Images
Product photos on a dark background often look fine. But if photos have a white background, they can look jarring in dark mode. Solution:
@media (prefers-color-scheme: dark) {
.product-image img {
mix-blend-mode: multiply; /* removes the white background from PNGs */
}
}
Or a CSS filter for softening:
html.dark .product-image img {
filter: brightness(0.9) contrast(1.05);
}
Colors in Bitrix Components
When editing styles for standard components (catalog, cart, search), add dark variants for each component. Strategy: create a separate _dark-theme.scss (or _dark-theme.css) file, included after the main styles, which overrides only what is needed for dark mode.
Templating in Bitrix
In component templates, use CSS variables instead of hardcoded values:
<!-- Before -->
<div style="background: #fff; color: #333;">
<!-- After -->
<div style="background: var(--color-surface); color: var(--color-text);">
For inline styles generated in PHP, take colors from configuration:
$bgColor = 'var(--color-surface)'; // Do not hardcode #ffffff
Testing
- Chrome DevTools: Rendering tab → Emulate CSS media feature
prefers-color-scheme - Switch the theme in the OS (Windows: Personalization → Colors, macOS: System Settings → Appearance)
- Verify the absence of FOWT — with browser cache disabled
Timeline
| Phase | Duration |
|---|---|
| Audit of current styles and extraction of color variables | 2 days |
| Dark theme palette development | 1 day |
| CSS variables and media query implementation | 2–3 days |
| Initialization script + toggle button | 1 day |
| Image and icon adjustments | 1 day |
| Cross-browser testing | 1 day |
| Total | 8–10 days |







