关于css:动态类名,其参数在Less mixin中

Dynamic classnames with parameters in Less mixin

我正在尝试创建一个Less mixin来生成媒体查询。 目的是将我的断点存储在variables.less文件中,并在它们之间循环以创建@media块。

然后将mixin用作:

1
2
3
.mq-medium({
  // rules
});

并生成CSS,例如:

1
2
3
@media only screen and (min-width: 640px) {
  // rules
}

这是我当前的mixin:

无变量

1
2
/* media queries */
@breakpoints: small 0, medium 640px, large 1024px, xlarge 1281px, xxlarge 1440px;

无媒体查询

1
2
3
4
5
6
7
8
9
10
11
12
13
.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传递给输出。 我以前使用静态类名来完成此操作,如下所示:

1
2
3
4
5
.mq-medium(@rules) {
  @media only screen and (min-width: extract(extract(@breakpoints, 2),2)) {
    @rules();
  }
}

那很好。

但是使用动态名称会导致错误。 我试过在.mq-@{breakpoint}语句中添加一个附加参数,例如:

1
2
3
4
5
.mq-@{breakpoint}(@rules) {
  @media only screen and (min-width: extract(extract(@breakpoints, @iterator),2)) {
    @rules();
  }
}

这导致各种错误。 如何通过包含的规则,以便将它们包含在mixin的输出中?


不,您不能在参数混合名称中使用变量。 因此,您不能通过标识符列表"生成" mixin。 因此,您需要发明其他方法...

嗯,有几种可能性-例如,请注意,mixin名称的@{breakpoint}部分只不过是另一个mixin参数。 然后可以将其编码为(简化):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 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();}
    }
}

---

或者,(仅为了说明那些"几种可能性"),实际上可以通过某些技巧和技巧使设备ID成为名称的前缀部分。 例如。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 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;
    }
});

这个技巧滥用了以下事实:变量可以用作规则集名称的一部分(然后我们可以将其用作非参数名称空间前缀),但是我永远不会为实际项目推荐此代码(它太hacky和有缺陷) 以任何方式)。