Перейти к содержанию

Слияние свойств

При создании набора примесей может понадобиться манипулировать значениями свойств, то есть адаптировать их в зависимости от контекста использования, используя условные конструкции (подробнее смотрите в главе 5).

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

.depth-top() {
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16);
}

.depth-bottom() {
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

Допустим, что имеется код, который генерирует одно и тоже свойство, но с разными значениями. В первом случае это будет тень сверху блока, а во-втором — снизу. С таким подходом можно встретиться в модном сейчас направлении — материальный дизайн. Вызовем эти примеси для какого-нибудь произвольного блока:

.block {
  .depth-top();
  .depth-bottom();
}

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

.block {
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16);
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

И проблема эта в том, что второе свойство переопределит первое. Это приведёт к тому, что тень не будет состоять из верхней и нижней частей — браузер покажет лишь нижнюю, так как она стоит ниже в селекторе и заменяет собой верхнюю.

Благодаря Less значения свойств можно конкатенировать, и делается это двумя способами:

  • Через запятую (свойства box-shadow, font-family и т.д.)
  • Через пробел (свойства transform, text-overflow и т.д.)

Слияние свойств через запятую

Для того, чтобы решить проблему, просто добавим плюс (+) перед двоеточием свойства. Это скажет компилятору, что при встречи двух одинаковых свойств в одном селекторе — его целью будет их объединение.

.depth-top() {
  box-shadow+: 0 2px 5px 0 rgba(0, 0, 0, 0.16);
}

.depth-bottom() {
  box-shadow+: 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

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

.block {
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}

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

Слияние свойств через пробел

По сути своей, никакого отличия от слияния свойств через запятую здесь нет — добавляется лишь нижнее подчёркивание после плюса перед двоеточием.

.scale(@scale) {
  transform+_: scale(@scale);
}

.rotate(@angle) {
  transform+_: rotate(@angle);
}

.translate(@px) {
  transform+_: translateX(@px);
}

.block {
  .scale(1.75);
  .rotate(45deg);
  .translate(10px);
}

В результате, после компиляции получим следующее валидное для этого свойства значение:

.block {
  transform: scale(1.75) rotate(45deg) translateX(10px);
}