Динамические имена классов с параметрами в миксине Less
Я пытаюсь создать миксин Less для генерации медиа-запросов. Цель состоит в том, чтобы хранить мои контрольные точки в variables.less
файл, и цикл по ним, чтобы создать @media
блоки.
Затем миксин будет использоваться как:
.mq-medium({
// rules
});
и генерировать CSS как:
@media only screen and (min-width: 640px) {
// rules
}
Вот мой текущий миксин:
variables.less
/* media queries */
@breakpoints: small 0, medium 640px, large 1024px, xlarge 1281px, xxlarge 1440px;
mediaqueries.less
.createMQClasses(@iterator:1) when(@iterator <= length(@breakpoints)-1) {
@breakpoint: extract(extract(@breakpoints, @iterator),1);
@breakpoint-next: extract(@breakpoints, (@iterator + 1));
@breakpoint-next-px: extract(@breakpoint-next, 2);
.mq-@{breakpoint} {
@media only screen and (min-width: extract(extract(@breakpoints, @iterator),2)) {
}
}
.createMQClasses((@iterator + 1));
}
.createMQClasses();
Пока мой код перебирает и генерирует пустой @media
блоки. Тем не менее, мне нужно передать любой @rules
до выхода. Я делал это ранее со статическими именами классов, например так:
.mq-medium(@rules) {
@media only screen and (min-width: extract(extract(@breakpoints, 2),2)) {
@rules();
}
}
И это прекрасно работает.
Но с динамическим именем это вызывает ошибки. Я попытался добавить дополнительный параметр в .mq-@{breakpoint}
заявления, как:
.mq-@{breakpoint}(@rules) {
@media only screen and (min-width: extract(extract(@breakpoints, @iterator),2)) {
@rules();
}
}
Это приводит к различным ошибкам. Как можно передать включенные правила, чтобы они были включены в вывод миксина?
1 ответ
Нет, вы не можете использовать переменные в именах параметрического миксина. Таким образом, вы не можете "генерировать" миксины по списку идентификаторов. Так что вам нужно придумать какой-то другой подход...
Ну, есть несколько возможностей - например, обратите внимание, что @{breakpoint}
часть имени миксина - это просто еще один параметр миксина. Тогда это может быть закодировано как-то вроде (упрощенно):
// usage:
@devices: small 0, medium 640px, large 1024px;
.mq(medium, {
foo {
bar: baz;
}
});
// impl.:
.mq(@id, @style) {
.-(length(@devices));
.-(@i) when (@i > 0) {
.-(@i - 1);
.--(extract(@devices, @i));
}
.--(@device) when (@id = extract(@device, 1)) {
@media (min-width: extract(@device, 2)) {@style();}
}
}
---
В качестве альтернативы (просто чтобы проиллюстрировать эти "несколько возможностей"), на самом деле можно сделать идентификатор устройства префиксной частью имени, используя определенные приемы и приемы. Например:
// impl.:
// (here mixin definitions should always go before their usage)
.make-media-mixins();
.make-media-mixins(@i: length(@devices)) when (@i > 0) {
.make-media-mixins(@i - 1);
@device: extract(@devices, @i);
@id: extract(@device, 1);
.@{id} {.mq(@rules) {
@media (min-width: extract(@device, 2)) {@rules();}
}}
}
// usage:
@devices: small 0, medium 640px, large 1024px;
.medium.mq({
foo {
bar: baz;
}
});
Этот трюк использует тот факт, что переменные могут использоваться как часть имени набора правил (а затем мы можем использовать его как непараметрический префикс пространства имен), но я бы никогда не рекомендовал этот код для реального проекта (он слишком хакерский и некорректный). с помощью любых средств).