Я написал приложение на Svelte и хотел бы добавить темный режим, который любой мог бы активировать после нажатия кнопки. Я добавил свойство isDarkMode, чтобы переключить два случая. Если свойство истинно, я хочу изменить цвет фона тела на темный цвет, но цвет фона не меняется.
{#if isDarkMode}
<style>
:global(body){
background: #2e3440;
}
</style>
{/if}
А почему не меняется. Стиль-блок, насколько я знаю, не является реактивным. После компиляции CSS извлекается «из» шаблона. Как определяется isDarkMode?
Вот демонстрация того, что я предлагаю svelte.dev/repl/ed4fef4beceb4b0eb295d1f9fdf3bd62?version=3.6.9
не могли бы вы сделать официальный ответ с этим?
@skyboyer Я отправил ответ сейчас.





Если вы хотите использовать переменные css для управления своими темами, вы можете переключать таблицы стилей в Svelte с помощью тега <svelte:head>:
<script>
let dark = false;
const toggleTheme = () => dark = dark === false
</script>
<svelte:head>
{#if dark}
<link rel = "stylesheet" href = "change/this/path/dark-theme.css">
{/if}
</svelte:head>
<h1>Hello World!</h1>
<button on:click = {toggleTheme}>
toggle theme
</button>
Это должно облегчить управление стилем в вашем приложении, а также уменьшить общий размер пакета и избежать использования селектора :global в css.
Вы можете найти рабочую демонстрацию здесь: https://svelte.dev/repl/1a121a39eddb4b3682a7701a35ac6824?version=3.6.9
Тег стиля в Svelte не является реактивным, как другие части файла Svelte (нужна ссылка). Итак, как только файл скомпилирован, создается CSS (уникальные идентификаторы, анимация и другие полезные вещи).
Я бы выбрал другой подход для реализации «Темного режима». Обычный подход для стран, не использующих CSS-in-JS, — добавить класс темы к тегу body.
Вам понадобится переключатель или что-то еще, чтобы активировать «темный режим» (например, время суток). В этом примере это компонент Button:
<script>
function toggle() {
window.document.body.classList.toggle('dark-mode')
}
</script>
<button on:click = {toggle}>Toggle mode</button>
Вот и все. Затем для вашего body и для других компонентов вы можете соответствующим образом оформить:
// App.svelte
<style>
:global(body) {
background-color: #f2eee2;
color: #0084f6;
transition: background-color 0.3s
}
:global(body.dark-mode) {
background-color: #1d3040;
color: #bfc2c7;
}
</style>
// Button.svelte or any other component that adjusts to mode
<style>
button {
background-color: #f76027;
color: white;
border: none;
border-radius: 4px;
padding: 0.5rem;
text-transform: uppercase;
}
:global(body.dark-mode) button {
background-color: #0084f6;
color: white;
}
</style>
Обратите внимание, что только часть тела (без каламбура) является глобальной :global(body.dark-mode). Если бы вы также поместили внутрь button, вы бы потеряли уникальный идентификатор, сгенерированный Svelte для вашего компонента, и это повлияло бы на все кнопки.
Я бы, наверное, выбрал другой подход. Если вы придерживаетесь CSS (в отличие от CSS-in-JS), я бы добавил имя класса темы в элемент body. Итак, у вас есть обычное телосложение и стиль
body.dark-mode. Тогда вам не нужны условные операторы, разбросанные по всему вашему приложению. (при условии, что вы укладываете больше, чем свое тело)