Определение переменных переменных с использованием LESS CSS
Скажем, у меня есть три отдельные цветовые схемы, которые используются на разных страницах сайта. Каждый цвет имеет определенный светлый, средний и темный оттенок, а цветовая схема определяется классом в теле. Предположим, что "красная" цветовая схема является стандартной. Вот так:
Определения цветов:
@red-lt: #121;
@red-md: #232;
@red-dk: #343;
@green-lt: #454;
@green-md: #565;
@green-dk: #676;
@blue-lt: #787;
@blue-md: #898;
@blue-dk: #909;
Основной пример стиля по умолчанию
body { background-color: @red-dk;
#container { background-color: @red-md;
p { color: @red-dk; }
}
}
Пример стиля цветовой схемы
body.green { background-color: @green-dk;
#container { background-color: @green-md;
p { color: @green-dk; }
}
}
Я бы хотел использовать переменные, так что мне не нужно переписывать все цветовые вариации для каждой схемы, так что я могу просто написать что-то вроде этого:
body.[color-var] { background-color: @[color-var]-dk;
#container { background-color: @[color-var]-md;
p { color: @[color-var]-dk; }
}
}
... но я не могу полностью обвести голову, как это сделать. Помощь...?
Ответы
Ответ 1
Используйте interpolation и escaping, круглые скобки в селекторе и параметрические микшины, чтобы получить желаемый эффект:
- Динамические переменные interpolation: в строке
"@{variable}"
заменяется значением переменной. Они также могут быть вложены: Учитывая @{@{var}-foo}
и @var: bar;
, результат "barfoo"
.
Полученное значение указывается. Чтобы удалить эти кавычки, префикс ~
.
- Динамические селектор Интерполяция селектора:
[email protected]{var}
превращается в body.bar
.
Пример:
@red-md: #232;
@red-dk: #343;
.setColor(@color) {
[email protected]{color} { background-color: ~"@{@{color}-dk}";
#container { background-color: ~"@{@{color}-md}";
p { color: ~"@{@{color}-md}"; }
}
}
}
.setColor(~"red"); // Escape to prevent "red" turning "#FF0000"
//.setColor(~"blue"); etc..
Входит в:
body.red {
background-color: #334433;
}
body.red #container {
background-color: #223322;
}
body.red #container p {
color: #223322;
}
Примечание. Когда ответ был изначально написан, интерполяция селектора не существовала. См. Предыдущую версию решения, если вы работаете со старым компилятором LESS (до LESS 1.3.1a). Поддержка старого метода будет сброшена в LESS 1.4.0.
Ответ 2
Если эти значения действительно соответствуют предсказуемому формату, похоже на идеальный вариант для параметрического mixin:
Минус:
@red: #232;
@green: #565;
@blue: #898;
.theme (@color) {
background-color: @color - #111;
#container {
background-color: @color;
p { color: @color + #111; }
}
}
body.red {
.theme(@red);
}
Скомпилированный CSS:
body.red{background-color:#112211;}
body.red #container{background-color:#223322;}
body.red #container p{color:#334433;}
Ответ 3
Я знаю, что этот вопрос довольно старый, но для тех, кто приходит на этот пост, мой ответ может помочь
Я не уверен, что вы хотите использовать это, но одно из моих предложений основано на ответе @ScottS. В моем реальном мире мне нужно создать веб-приложение, в котором будет показано, что несколько брендов и каждый бренд имеют свой собственный цвет текста, фон и т.д.... поэтому я начал преследовать способ выполнить это в LESS, что я можно легко сделать на SASS, и результат будет ниже:
МЕНЬШЕ
// Code from Seven Phase Max
// ............................................................
// .for
.for(@i, @n) {.-each(@i)}
.for(@n) when (isnumber(@n)) {.for(1, @n)}
.for(@i, @n) when not (@i = @n) {
.for((@i + (@n - @i) / abs(@n - @i)), @n);
}
// ............................................................
// .for-each
.for(@array) when (default()) {.for-impl_(length(@array))}
.for-impl_(@i) when (@i > 1) {.for-impl_((@i - 1))}
.for-impl_(@i) {.-each(extract(@array, @i))}
// Brands
@dodge : "dodge";
@ford : "ford";
@chev : "chev";
// Colors
@dodge-color : "#fff";
@ford-color : "#000";
@chev-color : "#ff0";
// Setting variables and escaping than
@brands: ~"dodge" ~"ford" ~"chev";
// Define our variable
.define(@var) {
@brand-color: '@{var}-color';
}
// Starting the mixin
.color() {
// Generating the loop to each brand
.for(@brands); .-each(@name) {
// After loop happens, it checks what brand is being called
.define(@name);
// When the brand is found, match the selector and color
[email protected]{name} & {
color: @@brand-color;
}
}
}
.carColor {
.color();
}
Результат Te будет:
CSS
.brand-dodge .carColor {
color: "#fff";
}
.brand-ford .carColor {
color: "#000";
}
.brand-chev .carColor {
color: "#ff0";
}
Это очень сложно, и я должен был использовать несколько элементов, чтобы получить то, что мне было нужно, сначала использовал набор mixins, предоставленный Seven Phase Max, и вы можете найти его здесь и чем, ответ @ScottS был частью, отсутствовавшей в моей головоломке... надеюсь, что это поможет вам и другим, которые должны создать набор переменных, чтобы быть частью другой переменной и создать более динамический файл меньшего размера.
Вы можете скопировать весь мой код и проверить его на http://lesstester.com/
Ответ 4
Насколько мне известно, имена переменных переменных не поддерживаются в LESS. Тем не менее вы могли бы реструктурировать свои объявления более семантически:
/* declare palette */
@red-lt: #121;
@red-md: #232;
@red-dk: #343;
@green-lt: #454;
@green-md: #565;
@green-dk: #676;
@blue-lt: #787;
@blue-md: #898;
@blue-dk: #909;
/* declare variables based on palette colors */
@lt: @red-lt;
@md: @red-md;
@dk: @red-dk;
/* ...and only use them for main declarations */
body { background-color: @dk;
#container { background-color: @md;
p { color: @dk; }
}
}
Это должно позволить вам переключаться между палитры совершенно безболезненно, избегая явных ссылок цвета.
Ответ 5
Попробуйте это
@red-lt: #121;
@red-md: #232;
@red-dk: #343;
@green-lt: #454;
@green-md: #565;
@green-dk: #676;
@blue-lt: #787;
@blue-md: #898;
@blue-dk: #909;
@color: 'red-lt';
div{
background: @@color;
border: 1px solid lighten(@@color,20%);
}