Можно ли использовать переменные CSS в массиве Twitter-bootstrap 4 $theme-colors?

В bootstrap 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); после запуска скрипта компиляции. Таким образом, загрузчик/компилятор не распознал мои переменные CSS как цвет...

Подводя итог, я хочу: изменить цвета начальной загрузки в зависимости от класса тела. Кто-нибудь знает способ добиться этого?

Укажите минимальный воспроизводимый пример, чтобы мы могли увидеть, как это не работает.

Asons 11.02.2019 18:10

ты пробовал "color-1":#{var(--theme-color-1)}

Temani Afif 15.02.2019 16:44

переменные начальной загрузки основаны на sass, это означает, что они будут генерироваться во время сборки. Таким образом, вы не можете вводить в него переменные css. Все, что вы можете сделать, это несколько раз включить весь бутстрап с разными переменными внутри корневых классов.

Sasan Farrokh 15.02.2019 23:25

@TemaniAfif Я пробовал это, но выдает ту же ошибку.

Dirk Jan 18.02.2019 09:54

@Sasan Farrokh Я думал об этом решении, но оно гораздо менее ремонтопригодно ...

Dirk Jan 18.02.2019 09:54

Есть предложение вынести выражения за пределы стилей SCSS и разрешить задавать их отдельными переменными github.com/twbs/bootstrap/issues/31538 , например вы можете увидеть PR, который показывает, как включить режим переменных CSS github.com/twbs/bootstrap/pull/31753

Dmitry Yaremenko 28.09.2020 09:14
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
22
6
7 940
3

Ответы 3

Вы не можете набор CSS-переменные в картах напрямую, потому что эта переменная не будет компилироваться в то время, так как SASS является препроцессором, кроме того, загрузчик все равно конвертирует эти KVP темы в переменные :root, поэтому вы по сути делаешь одно и то же дважды. Один из способов обойти это — вы можете просто подключиться к самой карте с помощью общих методов SASS:

  ...
  property: map-get(map-merge($theme-colors,($key : $color)),$key)
  ...

После того, как вы установите этот конкретный KVP, он будет доступен во всем мире для использования в других местах.

На данный момент использование CSS var() является произвольным, но просто чтобы охватить все мои основы, вы можете установить тему, а затем изменить переменную, в отличие от переустановки и вызова http://CDD5 .RU.

Полным примером этого может быть следующее:

@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>

Обратите внимание, что в примере также показано, устанавливает ли одна тема переменную, а другая нет. Выбранный вами цвет темы недействителен, и свойство возвращается к наследованию.

демонстрационная версия кода

Привет @soulshined, спасибо за ответ. Но как я могу изменить цвета начальной загрузки в зависимости от класса тела в вашем примере?

Dirk Jan 20.02.2019 08:34

Итак, скажем, я вызываю «set-theme-color» 20 раз, переменные начальной загрузки переопределяются 20 раз. Предположим, я вызываю цвет начальной загрузки после этого действия, как я узнаю, какой это цвет?

Dirk Jan 22.02.2019 10:54

@djl Ну, если после этого вы вызываете цвет начальной загрузки, вы бы знали, что это был последний набор правил, примененный на основе области действия, — это короткий ответ. переменные управляются областью действия. Цвет orange показывает, откуда вы это знаете. В моем примере вы знаете, что он оранжевый, потому что вы установили его либо раньше, либо с помощью элемента h3. Но даже если вы установите другой цвет для красной темы, это не будет зависеть от того, что хочет фиолетовая тема, потому что именно так работают каскадные таблицы стилей.

soulshined 22.02.2019 13:01

Мне нравится мой другой ответ, но я также хотел бы предложить другое решение, при условии, что оно не соответствует потребностям проекта. Другой вариант, и я думаю, что он больше соответствует вашим потребностям, заключается в том, что вы можете просто каскадировать свои таблицы стилей. Предположим, что дерево проекта выглядит следующим образом:

`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, поэтому вы должны изменить оператор импорта по мере необходимости.

Собственно это я и имел в виду. Но, как говорит @RMo, это дает ошибки при использовании таких функций, как darken().

Dirk Jan 22.02.2019 11:03

Есть предложение вынести выражения за пределы стилей SCSS и разрешить задавать их отдельными переменными github.com/twbs/bootstrap/issues/31538 , например вы можете увидеть PR, который показывает, как включить режим переменных CSS github.com/twbs/bootstrap/pull/31753

Dmitry Yaremenko 28.09.2020 09:13

Почему вы не можете использовать переменные 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, которую вы переопределяете, чтобы убедиться, что вы охватываете все случаи.

Удачи!

Спасибо за хорошее объяснение. Ошибка действительно может иметь какое-то отношение к функциям цвета. Поскольку я знаю, какие элементы используются на веб-сайте, я пока буду использовать это решение, хотя мне не нравится идея перезаписывать все вручную...

Dirk Jan 22.02.2019 11:01

Другие вопросы по теме