← Назад к вопросам
Как сделать кнопку смены темы влияющую на все контролы на экране без JavaScript?
2.0 Middle🔥 121 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Переключение темы без JavaScript (CSS-only подход)
Хотя полностью без JavaScript невозможно, можно минимизировать его использование. Существует CSS-only решение с использованием атрибутов и CSS селекторов.
CSS-only решение с checkbox hack
<label class="theme-toggle">
<input type="checkbox" id="theme-toggle" />
<span class="toggle-slider"></span>
</label>
<main>
<button>Click me</button>
<input type="text" placeholder="Type something" />
<div class="card">Content</div>
</main>
<style>
:root {
--color-bg: white;
--color-text: black;
--color-primary: blue;
}
#theme-toggle:checked ~ main {
--color-bg: #1e1e1e;
--color-text: #ffffff;
--color-primary: #00d4ff;
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}
button {
background-color: var(--color-primary);
color: var(--color-text);
}
input {
background-color: var(--color-bg);
color: var(--color-text);
border: 1px solid var(--color-primary);
}
</style>
С prefers-color-scheme (истинно без JS)
Самый чистый способ - использовать системные настройки:
:root {
--color-bg: white;
--color-text: black;
--color-primary: #0066cc;
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #1a1a1a;
--color-text: #ffffff;
--color-primary: #00d4ff;
}
}
body {
background-color: var(--color-bg);
color: var(--color-text);
transition: background-color 0.3s, color 0.3s;
}
button {
background-color: var(--color-primary);
color: var(--color-text);
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
input {
background-color: var(--color-bg);
color: var(--color-text);
border: 2px solid var(--color-primary);
padding: 8px;
}
Комбинированный подход (рекомендуемый)
function setupTheme() {
const toggle = document.getElementById('theme-toggle');
const saved = localStorage.getItem('theme');
if (saved === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
toggle.checked = true;
}
}
export function ThemeToggle() {
return (
<label className="theme-toggle">
<input
type="checkbox"
id="theme-toggle"
onChange={(e) => {
document.documentElement.setAttribute(
'data-theme',
e.target.checked ? 'dark' : 'light'
);
localStorage.setItem(
'theme',
e.target.checked ? 'dark' : 'light'
);
}}
/>
<span className="toggle-slider"></span>
</label>
);
}
const css = `
:root {
--color-bg: white;
--color-text: #000;
--color-primary: #0066cc;
}
[data-theme="dark"] {
--color-bg: #1a1a1a;
--color-text: #fff;
--color-primary: #00d4ff;
}
body {
background-color: var(--color-bg);
color: var(--color-text);
transition: background-color 0.3s ease, color 0.3s ease;
}
button, input, textarea, select {
background-color: var(--color-bg);
color: var(--color-text);
border-color: var(--color-primary);
}
`;
Продвинутое CSS решение с CSS Variables
:root {
--palette-primary: hsl(210, 100%, 50%);
--palette-primary-dark: hsl(210, 100%, 40%);
--palette-bg-light: hsl(0, 0%, 100%);
--palette-bg-dark: hsl(0, 0%, 10%);
--palette-text-light: hsl(0, 0%, 0%);
--palette-text-dark: hsl(0, 0%, 100%);
--color-bg: var(--palette-bg-light);
--color-text: var(--palette-text-light);
--color-primary: var(--palette-primary);
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: var(--palette-bg-dark);
--color-text: var(--palette-text-dark);
--color-primary: var(--palette-primary-dark);
}
}
[data-theme="light"] {
--color-bg: var(--palette-bg-light);
--color-text: var(--palette-text-light);
--color-primary: var(--palette-primary);
}
[data-theme="dark"] {
--color-bg: var(--palette-bg-dark);
--color-text: var(--palette-text-dark);
--color-primary: var(--palette-primary-dark);
}
* {
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
React компонент с системными настройками
function App() {
const [theme, setTheme] = React.useState('system');
React.useEffect(() => {
const root = document.documentElement;
if (theme === 'system') {
root.removeAttribute('data-theme');
} else {
root.setAttribute('data-theme', theme);
}
localStorage.setItem('theme', theme);
}, [theme]);
return (
<div>
<button onClick={() => setTheme('light')}>Light</button>
<button onClick={() => setTheme('dark')}>Dark</button>
<button onClick={() => setTheme('system')}>System</button>
<main>
{/* Content */}
</main>
</div>
);
}