【问题标题】:Using undefined number of arguments in mixins在 mixins 中使用未定义数量的参数
【发布时间】:2012-06-13 11:04:18
【问题描述】:

我的 Less CSS 表中目前有 -webkit 特定属性,我正在尝试使用 mixins 更新它们以添加 -moz 属性,如下所示:

.transition(@1) {
    -webkit-transition: @1;
    -moz-transition: @1;
}

div {
    .transition(all .5s);
}

上面的例子很好用,但是我也有类似的东西:

div {
    -webkit-transition: border-color .3s, background .3s;
}

我不能将mixin 称为.transition(border-color .3s, background .3s),因为它的参数比mixin 中定义的要多。所以我现在正在做的是:

.transition(@1) {
    -webkit-transition: @1;
    -moz-transition: @1;
}
.transition-2(@1, @2) {
    -webkit-transition: @1, @2;
    -moz-transition: @1, @2;
}

div {
    .transition-2(border-color .3s, background .3s);
}

这很烦人,每当我使用许多以前未使用过的参数时,我都需要在工作表中添加冗余代码;我在其他 CSS3 属性中也有这个问题,例如 box-shadow 当我需要在开头添加 inset 时。

有什么方法可以用 Less 声明 mixins 灵活的参数数量,就像 CSS3 属性一样?

【问题讨论】:

  • 别以为你还在寻找这个伙伴的答案。但从不判断。这个问题的观点,我认为基于最新选项的答案会增加很多价值。

标签: css less less-mixins


【解决方案1】:

对于这种情况,可以使用以下任何一种选项来避免多余的 mixin 代码。

选项 1:(最简单的解决方案 - 感谢 highlighting the miss 的最大七阶段)

我们可以使用分号作为参数的分隔符/定界符,当我们在指定所有需要转换的属性(以逗号分隔的格式)后在末尾添加分号时,它之前的整个部分将被视为一个单一的论点。

official Less website中提取:

使用逗号作为 mixin 分隔符使得无法创建逗号分隔的列表作为参数。另一方面,如果编译器在 mixin 调用或声明中看到至少一个分号,则假定参数用分号分隔,并且所有逗号都属于 css 列表

.transition(@1) {
    -webkit-transition: @1;
    -moz-transition: @1;
}

div{
    .transition(border-color .5s, background .3s, color .3s;);
}

所以上面的代码在编译时会导致

div {
    -webkit-transition: border-color 0.5s, background 0.3s, color 0.3s;
    -moz-transition: border-color 0.5s, background 0.3s, color 0.3s;
}

选项 2:

在引号内将输入值传递给 mixin(需要转换多少特定属性)。在 mixin 中,使用 ~e() 内置函数去除引号。

.transition(@1) {
    -webkit-transition: ~"@{1}";
    -moz-transition: ~"@{1}";
}

div {
    .transition("border-color .5s, background .3s");
}
div#sample2 {
    .transition("border-color .3s, background .3s, color .3s");
}

编译后会生成下面的 CSS

div {
    -webkit-transition: border-color .5s, background .3s;
    -moz-transition: border-color .5s, background .3s;
}
div#sample2 {
    -webkit-transition: border-color .3s, background .3s, color .3s;
    -moz-transition: border-color .3s, background .3s, color .3s;
}

选项 3:

Less 确实允许使用 ... 选项创建允许/接受可变数量输入的 mixin。因此,您可以通过将 ... 添加到输入变量并按照您最初想要的方式调用它来使用与原始代码中相同的 mixin。

.transition(@args...) {
    -webkit-transition: @args;
    -moz-transition: @args;
}

div {
    .transition(border-color .5s, background .3s);
}

上面会成功编译,但唯一的问题是编译时会产生以下输出。如您所见,问题在于参数值是空格分隔的,而不是逗号分隔的(因为它们应该是 CSS 正常工作的原因)。

div {
    -webkit-transition: border-color 0.5s background 0.3s;
    -moz-transition: border-color 0.5s background 0.3s;
}

当然,我们可以使用正则表达式编写复杂的replace 函数,但这确实会使代码变得混乱。相反,我们可以使用循环和一些内置函数来实现所需的输出(如下所示)。

.transition(@args...) {
    .loop-args(@argCount) when (@argCount > 0) {
        .loop-args(@argCount - 1);
        @arg: extract(@args, @argCount);
        -webkit-transition+: @arg;
        -moz-transition+: @arg;
    }
    .loop-args(length(@args));
}

div {
    .transition(border-color .5s, background .3s, color .3s);
}

基本上我们所做的是使用... 接受多个参数作为mixin 的输入,然后循环遍历每个参数并将其添加到CSS 属性的值中。 +:(Less v1.5.0 中引入的合并功能)用于生成逗号分隔的输出。

编译后会产生如下输出:

div {
    -webkit-transition: border-color 0.5s, background 0.3s, color 0.3s;
    -moz-transition: border-color 0.5s, background 0.3s, color 0.3s;
}

【讨论】:

  • 我想你忘记了最简单的解决方案:.transition(border-color .5s, background .3s;);
  • @seven-phases-max:哎呀,真的。我确实忘记了我们可以使用; 作为参数分隔符。感谢您强调这一点。我正在更新答案。
【解决方案2】:

你可以试试

.transition(@1) {
    -webkit-transition: @1;
    -moz-transition: @1;
}
.transition-2(@1, @2) {
    .transition(@1); // this includes all the stuff from transition(@1)
    color:red; // additional stuff
}

至于你的实际问题,我不相信 LESS 本身有任何“休息”风格的参数通过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    相关资源
    最近更新 更多