Я думаю, что основной проблемой здесь будет @y/@x
. Попробуйте @x/@y
, и это должно дать что-то более ожидаемое ;-)
Поскольку вложенные миксины интерпретируются по-разному в разных реализациях less, теперь я разделю ответ на две части:
1. Решение, которое работало на less2css.org с LESS > 1.3.1 (с использованием ваших вложенных миксинов)
В противном случае я думаю, что приведенный выше код действительно делает то, что вы хотите, на less2css.org. Как и в LESS 1.4, вам нужно быть осторожным с математикой, так как по умолчанию она должна быть заключена в скобки.
Если вы сейчас просто вызовете такой миксин для невложенных правил, например
.b { .foo(@y); }
вам нужно использовать единицы измерения во входной переменной или добавить unit()
в свой миксин, иначе вы получите только то число, которое вы ввели, например 2:
.foo(@x) {
width: unit(@x,px);
.foo(@y) {
width: (@x/@y);
}
}
.a {
.foo(20px);
.b{
.foo(2);
}
}
.c {
.foo(2);
}
выведет CSS:
.a {
width: 20px;
}
.a .b {
width: 10px;
}
.c {
width: 2px;
}
Вы можете стать еще более изобретательным и проверить у охранников, имеет ли атрибут в подклассе пиксели как единицу, чтобы вы также могли вкладывать классы, в которых вы не передаете фактор:
.foo(@x) {
width: @x;
.foo(@y) when (ispixel(@y)) {
width: @y;
}
.foo(@y) when not (ispixel(@y)) {
width: (@x/@y);
}
}
Однако тестирование этого вложенного миксина работает только на less2css.org, но не на jsbin.com, lesstester.com и некоторых других сервисах [где вам нужно вызвать вложенный (второй) уровень миксина с помощью .foo .too
, чтобы применить второй уровень стилизации от миксина].
Поэтому я предлагаю альтернативный подход, который я протестировал, и он, кажется, работает на всех упомянутых страницах с использованием компиляторов less-css с less> 1.2.
2. Решение с использованием охранников с ispixel
, которое должно работать на большинстве установок LESS > 1.2.
Вместо вашего вложенного миксина вы можете создать два миксина, которые основаны на проверке охранников на пиксели как единицу измерения.
- если атрибут
@x
указан в пикселях => вернуть width:@x;
и присвоить @x
переменной @width
- если атрибут
@x
не в пикселях => вернуть width:@width/@x;
(примечание: @width
необходимо предварительно назначить, сначала вызвав миксин с @x
в px
)
пример МЕНЬШЕ:
.foo(@x) when (ispixel(@x)) {
width:@x;
@width:@x;
}
.foo(@x) when not (ispixel(@x)) {
width: (@width/@x);
}
.a, .b {
background-color: #ddd;
height: 100px;
}
.a {
.foo(100px);
.b {
background-color: red;
.foo(2);
}
}
выходной CSS:
.a, .b {
background-color: #ddd;
height: 100px;
}
.a {
width: 100px;
}
.a .b {
background-color: red;
width: 50px;
}
Отличается от вашего подхода, но, возможно, немного более прямолинеен и, кажется, работает хорошо.
Редактировать:
Так как вы не хотите различать ввод с модулем и ввод без модуля, я могу думать только о вызове двухпараметрического миксина, где один параметр используется для базы (width
в вашем случае) а второй как фактор, который по умолчанию равен 1. И теперь вы можете вызывать его рекурсивно столько раз, сколько захотите.
МЕНЬШЕ:
.foo(@x,@y:1){
width:unit(@parent,px);
@parent:(@x/@y);
}
.a {
.foo(100px);
.b{
.foo(@parent,2px);
.c{
.foo(@parent,5px);
.d{
.foo(@parent,0.05);
}
}
}
}
вывод CSS:
.a {
width: 100px;
}
.a .b {
width: 50px;
}
.a .b .c {
width: 10px;
}
.a .b .c .d {
width: 200px;
}
Так что теперь не имеет значения, какая единица измерения у входа, потому что вы можете назначить желаемую единицу для вывода в миксине. Когда вы вызываете миксин, он перезаписывает переменную @parent
для текущей области видимости, которая затем наследуется во вложенных правилах, где вы можете использовать ее в качестве параметра ширины @x
при повторном вызове миксина. Это должно дать вам желаемый результат.
person
Martin Turjak
schedule
14.04.2013