I'm trying to create a Less mixin to generate media queries. The goal is to store my breakpoints in a variables.less
file, and loop through them to create @media
blocks.
The mixin would then be used as:
.mq-medium({
// rules
});
and generate CSS like:
@media only screen and (min-width: 640px) {
// rules
}
Here's my current mixin:
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();
So far my code loops through and generates empty @media
blocks. However, I need to pass any @rules
through to the output. I've done this with static classnames previously, like this:
.mq-medium(@rules) {
@media only screen and (min-width: extract(extract(@breakpoints, 2),2)) {
@rules();
}
}
And that works fine.
But with the dynamic name it's causing errors. I've tried adding an additional parameter to the .mq-@{breakpoint}
statements, like:
.mq-@{breakpoint}(@rules) {
@media only screen and (min-width: extract(extract(@breakpoints, @iterator),2)) {
@rules();
}
}
This results in various errors. How can pass the included rules through so they're included in the mixin's output?
No, you can't use variables in parametric mixin names. Thus you can't "generate" mixins by a list of identifiers. So you need to invent some other approach...
Well, there're several possibilities - for example notice that
@{breakpoint}
part of the mixin name is nothing but just another mixin parameter. Then it could be coded as something like (simplified):---
Alternatively (just to illustrate those "several possibilities"), it is actually possible to make the device id to be a prefix part of the name via certain tricks&hacks. E.g.:
This trick abuses the fact that variables can be used as part of a ruleset name (and then we can use it as a non-parametric namespace prefix), but I would never recommend this code for a real project (it's just too hacky and flawed by any means).