LESS:如何将一个 mixin 作为参数传递给另一个 mixin?
LESS: How can I pass a mixin as an argument to another mixin?
我有一些基本的 mixin,它们使用媒体查询应用一些规则
.on-small(@rules) {
@media (@minWidthSmall) { @rules(); }
}
.on-medium(@rules) {
@media (@minWidthMedium) { @rules(); }
}
// and .on-large, .on-x-large and so on
我正在尝试构建一个非常简单的基于 flex 的网格系统,我正在尝试将提到的 mixin 作为参数传递,这样我就可以拥有一个通用的 .make-column
mixin。如下:
.make-col(@break-point-mixin, @span, @size) {
flex: 1;
box-sizing: border-box;
/***********************************************************
Is the following line possible in LESS somehow?
***********************************************************/
@break-point-mixin({
width: percentage(@span/@size);
min-width: percentage(@span/@size);
});
}
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@break-point-mixin: .on-small, @span, @size);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@break-point-mixin: .on-medium, @span, @size);
}
但不幸的是,将 @break-point-mixin
作为参数传递并从 .make-col
内部调用它会崩溃:
Unrecognised input. Possibly missing opening '('
不,您不能将 mixin 名称作为参数发送并以这种方式使用它。
相反,您可以执行类似下面的操作,其中直接从包装器混合中调用媒体查询混合,而不是 .make-col
混合。由于包装器 mixin 知道媒体查询 mixin 需要的变量,所以这不会导致任何问题。
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-small({
width: percentage(@span / @size);
min-width: percentage(@span / @size);
});
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-medium({
width: percentage(@span / @size);
min-width: percentage(@span / @size);
});
}
如果您担心重写上述 mixins 中的规则,那么您可以将它们设置为如下规则集并使用它。
@colRules: {
width: percentage(@span / @size);
min-width: percentage(@span / @size);
};
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-small(@colRules);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-medium(@colRules);
}
或者,您可以将 mixin 名称作为参数发送,并像下面这样使用守卫。由于我们在这里处理 break-points 并且应该不会有很多,这种方法应该会有所帮助并且可能会得到我的投票。
@colRules: {
width: percentage(@span / @size);
min-width: percentage(@span / @size);
};
.make-col(@breakpoint, @span, @size) {
flex: 1;
box-sizing: border-box;
& when (@breakpoint = s) {
.on-small(@colRules); /* or you could replace this with that mixin's content also */
}
& when (@breakpoint = m) {
.on-medium(@colRules);
}
/* and so on for the rest */
}
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(s, @span, @size);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(m, @span, @size);
}
在这种特殊情况下(与具有任意混合名称的一般情况不同)我会说你错过了 .on-small
/.on-medium
这些 small
和medium
东西也不过是参数,因此不应该成为混合名称的一部分。考虑到这一点,您的示例变为:
.on(small, @rules) {
@media (@minWidthSmall) {@rules();}
}
.on(medium, @rules) {
@media (@minWidthMedium) {@rules();}
}
.make-col(@device, @span, @size) {
flex: 1;
box-sizing: border-box;
.on(@device, {
width: percentage(@span/@size);
min-width: percentage(@span/@size);
});
}
// usage:
.make-col(small, @span, @size);
你的 .grid-col-on-*
mixin 也一样,它们只是一个:
.grid-col-on(@device, @span: 1, @size: 1) {
.make-col(@device, @span, @size);
}
等等。
如果你真的想要一个 flexible/generic 网格 - 永远不要 将 device/breakpoint 名称硬编码到 mixin 或变量名称中(有关更多原理和示例,请参见 https://github.com/less/less.js/issues/2702).
我有一些基本的 mixin,它们使用媒体查询应用一些规则
.on-small(@rules) {
@media (@minWidthSmall) { @rules(); }
}
.on-medium(@rules) {
@media (@minWidthMedium) { @rules(); }
}
// and .on-large, .on-x-large and so on
我正在尝试构建一个非常简单的基于 flex 的网格系统,我正在尝试将提到的 mixin 作为参数传递,这样我就可以拥有一个通用的 .make-column
mixin。如下:
.make-col(@break-point-mixin, @span, @size) {
flex: 1;
box-sizing: border-box;
/***********************************************************
Is the following line possible in LESS somehow?
***********************************************************/
@break-point-mixin({
width: percentage(@span/@size);
min-width: percentage(@span/@size);
});
}
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@break-point-mixin: .on-small, @span, @size);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@break-point-mixin: .on-medium, @span, @size);
}
但不幸的是,将 @break-point-mixin
作为参数传递并从 .make-col
内部调用它会崩溃:
Unrecognised input. Possibly missing opening '('
不,您不能将 mixin 名称作为参数发送并以这种方式使用它。
相反,您可以执行类似下面的操作,其中直接从包装器混合中调用媒体查询混合,而不是 .make-col
混合。由于包装器 mixin 知道媒体查询 mixin 需要的变量,所以这不会导致任何问题。
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-small({
width: percentage(@span / @size);
min-width: percentage(@span / @size);
});
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-medium({
width: percentage(@span / @size);
min-width: percentage(@span / @size);
});
}
如果您担心重写上述 mixins 中的规则,那么您可以将它们设置为如下规则集并使用它。
@colRules: {
width: percentage(@span / @size);
min-width: percentage(@span / @size);
};
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-small(@colRules);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(@span, @size);
.on-medium(@colRules);
}
或者,您可以将 mixin 名称作为参数发送,并像下面这样使用守卫。由于我们在这里处理 break-points 并且应该不会有很多,这种方法应该会有所帮助并且可能会得到我的投票。
@colRules: {
width: percentage(@span / @size);
min-width: percentage(@span / @size);
};
.make-col(@breakpoint, @span, @size) {
flex: 1;
box-sizing: border-box;
& when (@breakpoint = s) {
.on-small(@colRules); /* or you could replace this with that mixin's content also */
}
& when (@breakpoint = m) {
.on-medium(@colRules);
}
/* and so on for the rest */
}
.grid-col-on-small(@span: 1, @size: 1) {
.make-col(s, @span, @size);
}
.grid-col-on-medium(@span: 1, @size: 1) {
.make-col(m, @span, @size);
}
在这种特殊情况下(与具有任意混合名称的一般情况不同)我会说你错过了 .on-small
/.on-medium
这些 small
和medium
东西也不过是参数,因此不应该成为混合名称的一部分。考虑到这一点,您的示例变为:
.on(small, @rules) {
@media (@minWidthSmall) {@rules();}
}
.on(medium, @rules) {
@media (@minWidthMedium) {@rules();}
}
.make-col(@device, @span, @size) {
flex: 1;
box-sizing: border-box;
.on(@device, {
width: percentage(@span/@size);
min-width: percentage(@span/@size);
});
}
// usage:
.make-col(small, @span, @size);
你的 .grid-col-on-*
mixin 也一样,它们只是一个:
.grid-col-on(@device, @span: 1, @size: 1) {
.make-col(@device, @span, @size);
}
等等。
如果你真的想要一个 flexible/generic 网格 - 永远不要 将 device/breakpoint 名称硬编码到 mixin 或变量名称中(有关更多原理和示例,请参见 https://github.com/less/less.js/issues/2702).