Можно ли использовать CSS-переменные в массиве Twitter-bootstrap 4 $ theme-colors?
В начальной загрузке 4 вы можете определить и/или переопределить цвета по умолчанию, используя следующий массив: (как описано здесь)
$theme-colors: (
"primary": #001122, /*override*/
"color-1": red, /*new color*/
"color-2": black, /*new color*/
"color-3": white /*new color*/
);
Я хочу сделать собственные цвета темы для разных пользователей. Пользователи могут выбирать разные цветовые палитры, которые я определил в зависимости от класса тела.
Я создал новый файл для создания своих собственных стилей, определяя цвета моей темы в переменных CSS в теге body:
body {
&.color-pallette-red {
--theme-color-1: red;
--theme-color-2: black;
--theme-color-3: white;
color: var(--theme-color-1); /*red*/
}
&.color-pallette-yellow {
--theme-color-1: yellow;
--theme-color-2: black;
--theme-color-3: white;
color: var(--theme-color-1); /*yellow*/
}
}
Но при этом цвета начальной загрузки, конечно, не перезаписываются...
Я попытался вставить мои CSS-переменные в массив начальной загрузки, упомянутый ранее, чтобы убедиться, что загрузчик использовал мои цвета:
$theme-colors: (
"color-1": var(--theme-color-1),
"color-2": var(--theme-color-2),
"color-3": var(--theme-color-3)
);
Но это возвращает Error: $color2: var(--theme-color-1) is not a color. @return mix($color-base, $color, $level * $theme-color-interval);
Error: $color2: var(--theme-color-1) is not a color. @return mix($color-base, $color, $level * $theme-color-interval);
после запуска скрипта компиляции. Таким образом, загрузчик/компилятор не распознал мои CSS-переменные как цвет...
Подводя итог, я хочу: изменить цвета начальной загрузки в зависимости от класса тела. Кто-нибудь знает способ добиться этого?
Ответы
Ответ 1
Вы не можете установить CSS-переменные в картах напрямую, потому что эта переменная не будет скомпилирована в данный момент, так как SASS является препроцессором, кроме того, bootstrap оборачивается и конвертирует эти тематические KVP в :root
переменные в любом случае, так что вы по сути делаете одно и то же дважды. Одним из способов решения этой проблемы является то, что вы можете просто подключиться к самой карте с помощью общих методов SASS
:
...
property: map-get(map-merge($theme-colors,($key : $color)),$key)
...
После того, как вы установили этот конкретный KVP, он будет доступен для использования в других местах.
На этом этапе произвольно использовать CSS var()
, но чтобы охватить все мои основы, вы можете установить тему, а затем изменить переменную, в отличие от переустановки и вызова theme-color("color-2")
Полный пример этого будет следующим:
@import "bootstrap";
$theme-colors: (
"primary": #001122,
"color-1": black,
"color-2": black,
"color-3": black
);
@function set-theme-color($key, $color) {
@return map-get(map-merge($theme-colors,($key : $color)),$key);
}
@mixin theme($color1, $color2, $color3) {
background-color: set-theme-color("color-1", $color1);
h1 {
color: set-theme-color("color-2", $color2);
}
h2 {
color: set-theme-color("color-3", $color3);
}
}
main {
&.theme-purple {
@include theme(purple,cornflowerblue,white);
/* example demonstrating color3 can change */
--color-3: orange;
}
&.theme-red {
@include theme(red,black,white);
}
}
h2 {
color: theme-color("color-2");
}
h3 {
/* example demonstrating color3 changed */
color: var(--color-3);
}
<script src="http://codeply.com/js/embed.js"></script><div data-codeply="o9n2ST6HW5" ></div>
Ответ 2
Мне нравится мой другой ответ, но я также хотел бы предложить другое решение при условии, что оно не соответствует потребностям проекта. Другой вариант, и я думаю, что более прямой к вашим потребностям, заключается в том, что вы можете просто каскадировать таблицы стилей. Предполагая, что дерево проекта выглядит следующим образом:
'css\
'--main.css
'--themes.css <- compiled themes.sass
'--themes.sass
'index.html
Где index.html
:
...
<head>
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css">
<link rel="stylesheet" type="text/css" media="screen" href="css/themes.css">
</head>
<body>
<main class="theme-purple">
<h1>Hello World</h1>
<h2>SASS is fun!</h2>
</main>
<main class="theme-red">
<h1>Hello World</h1>
<h2>SASS is fun!</h2>
</main>
</body>
...
Где main.css
:
.theme-red {
--theme-color-1: red;
--theme-color-2: black;
--theme-color-3: white;
}
.theme-purple {
--theme-color-1: purple;
--theme-color-2: cornflowerblue;
--theme-color-3: white;
}
Где themes.sass
.
@import "node_modules/bootstrap/scss/bootstrap";
$theme-colors: (
"primary": #001122,
"color-1": var(--theme-color-1),
"color-2": var(--theme-color-2),
"color-3": var(--theme-color-3)
);
main {
background-color: theme-color("color-1");
}
h1 {
color: theme-color("color-2");
}
h2 {
color: theme-color("color-3")
}
Таким образом, ваши CSS-переменные могли скомпилироваться. Я проверил на сервере node.js, поэтому вы должны изменить оператор импорта по мере необходимости
Ответ 3
Почему вы не можете использовать переменные CSS для цветов в SASS
Причиной, по которой вы не можете использовать CSS-переменные для цветов, являются такие функции, как darken()
и lighten()
в SASS. Вы можете представить, что компьютер не будет знать, что делать, когда получит инструкцию: darken( var(--color), 20%)
; Вы не можете изменить значение, о котором вы не знаете.
Что если мы просто не используем функции, которые меняют цвета?
На самом деле это должно работать. В библиотеке начальной загрузки есть scss файлы, которые используют эти функции. Вы можете пройти через весь загрузочный код и удалить функции, которые изменяют цвета. Конечно, это будет немного работы. Обновление начальной загрузки в будущем может привести к таинственному краху стиля вашего сайта, и кто-то будет очень зол на вас. Так что этот вариант не очень хорошая идея.
Но... Но... Если CSS может сделать это, вы можете с SASS?
ДА! Это ответ. И это будет довольно много работы. Если вы устанавливаете цвета с помощью другой переменной, вы можете использовать переменную SASS, например, --color
для этих цветов. Например:
$color1: var(--color-1);
/* It may seem completely redundant to
to define CSS variable here. But
it isn't. You can change the variables in
your browser now with JavaScript, which
may affect multiple elements.
*/
:root{
--color-1: purple;
}
/* An example on how to change the page
styling with an id.
*/
:root#dark-mode{
--color-1: black;
}
.alert-success{
background-color: $color1;
}
.alert-danger{
background-color: $color1;
}
К счастью, разработчики bootstrap 4 проделали довольно хорошую работу по сохранению своих селекторов простыми, поэтому переписать их будет не сложно. Не забудьте загрузить свой CSS после начальной загрузки CSS. Возможно, вы захотите найти в файлах scss начальной загрузки переменную SASS, которую вы переопределяете, чтобы убедиться, что вы охватили все случаи.
Удачи!