Налаштування перемикача темної/світлої теми 1С-Бітрікс
Перемикач теми — невеликий UI-компонент: кнопка або тумблер у шапці сайту, при натисканні на який змінюється тема. Завдання вирішується повністю на фронтенді та не вимагає змін у PHP-коді Бітрікса, лише правильного вбудовування в шаблон.
HTML-розмітка перемикача
Простий тумблер з іконками сонця та місяця:
<button
id="theme-toggle"
class="theme-toggle"
aria-label="Переключити тему"
title="Переключити тему"
>
<svg class="icon-sun" viewBox="0 0 24 24" width="20" height="20">
<!-- іконка сонця -->
</svg>
<svg class="icon-moon" viewBox="0 0 24 24" width="20" height="20">
<!-- іконка місяця -->
</svg>
</button>
CSS для станів:
.theme-toggle .icon-moon { display: none; }
.theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
JavaScript перемикання
const toggle = document.getElementById('theme-toggle');
toggle.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
// Якщо потрібно зберегти для авторизованих користувачів на сервері:
if (window.BX && BX.ajax) {
BX.ajax.post('/local/ajax/save-theme.php', {theme: next});
}
});
Вбудовування в шаблон Бітрікса
У файлі header.php шаблону сайту розміщуєте кнопку в потрібному місці шапки. Інлайновий скрипт визначення теми (для запобігання FOUC) має йти першим у <head>:
<!-- У <head>, до підключення стилів -->
<script>
(function() {
var t = localStorage.getItem('theme')
|| (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', t);
document.documentElement.classList.add('theme-ready');
})();
</script>
Клас theme-ready допомагає прибрати transition-анімацію при першому завантаженні:
/* Вимикаємо анімацію до готовності теми */
html:not(.theme-ready) * { transition: none !important; }
Плавний перехід між темами
Щоб зміна теми не була різкою:
body,
body *:not(.no-transition) {
transition: background-color 0.2s ease, color 0.2s ease,
border-color 0.2s ease, box-shadow 0.2s ease;
}
Додавайте перехід лише на конкретні CSS-властивості кольору — не transition: all, інакше будуть гальмувати анімації контенту.
Збереження теми для авторизованих користувачів
Для авторизованих користувачів тему можна зберігати в профілі, щоб вона застосовувалась одразу при рендері на сервері без миготіння:
// /local/ajax/save-theme.php
if ($USER->IsAuthorized()) {
$theme = in_array($_POST['theme'], ['dark', 'light']) ? $_POST['theme'] : 'light';
CUser::Update($USER->GetID(), ['UF_THEME' => $theme]);
}
У header.php:
<?php
$savedTheme = 'light';
if ($USER->IsAuthorized()) {
$userFields = CUser::GetByID($USER->GetID())->Fetch();
$savedTheme = $userFields['UF_THEME'] ?? 'light';
}
?>
<html data-theme="<?= htmlspecialchars($savedTheme) ?>">
У цьому випадку інлайновий скрипт у <head> все одно потрібен — він перекриває серверне значення уподобанням з localStorage для неавторизованих.
| Етап | Час |
|---|---|
| Розмітка та стилі перемикача | 1–2 год |
| JS-логіка перемикання + localStorage | 1–2 год |
| Запобігання FOUC (інлайновий скрипт) | 1 год |
| Плавні переходи (CSS transitions) | 1 год |
| Збереження в профілі користувача (опційно) | 2–3 год |







