Developing a design adaptation for 1C-Bitrix's prefers-color-scheme

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

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