Я делал следующим образом.
Набор переменных для темы по умолчанию:
:root {
--color1: white;
}
Переопределения переменных для темной темы:
body.dark {
--color1: black;
}
В шаблоне страницы (именно там, для предотвращения "мерцания" при загрузке страницы) читаем тему из локального хранилища:
<body>
<script>
if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
</script>
Кнопка для переключения темы:
<li class="nav-item theme-switcher-outer">
<a class="nav-link theme-switcher" href="javascript:switchTheme()">
<i class="fa fa-sun theme-switcher__light"></i>
<i class="fa fa-moon theme-switcher__dark"></i>
</a>
</li>
Стили для переключения иконки в кнопке:
.theme-switcher {
&__light { display: none; }
&__dark { }
body.dark & {
&__light { display: inline; }
&__dark { display: none; }
}
}
И сама функция переключения:
function switchTheme() {
document.body.classList.toggle('dark');
localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
}