我注意到用SASS编写的inuit.css具有.vendor混合:
@mixin vendor($property, $value...){
-webkit-#{$property}:$value;
-moz-#{$property}:$value;
-ms-#{$property}:$value;
-o-#{$property}:$value;
#{$property}:$value;
}
有没有办法在LESS中使用一些奇怪的功能(例如e()和@ {})来复制它?
最佳答案
更新:LESS> = 1.6
从1.6版开始(请参见 changelog ),在LESS中实现了属性名称插值。因此,您不再需要任何魔术。 (对于较旧的版本,请参阅我的原始答案。)
您的mixin基本上可以按以下方式工作:
减:
.vendor(@property; @value){
-webkit-@{property}: @value;
-moz-@{property}: @value;
-ms-@{property}: @value;
-o-@{property}: @value;
@{property}: @value;
}
/*example*/
.test {
.vendor(transform, translateX(20px));
}
CSS:.test {
-webkit-transform: translateX(20px);
-moz-transform: translateX(20px);
-ms-transform: translateX(20px);
-o-transform: translateX(20px);
transform: translateX(20px);
}
原始答案:LESS <1.6
据我所知,很少有人没有添加对动态插入属性的支持,这在前面已经讨论了很多次,请参见:
因此,通常的方式是使用参数混合和模式匹配...这样会增加一些硬编码...但是属性和不同的供应商有时仍然需要稍微不同的参数格式,因此需要更多的控制以这种方式添加。
解决方法#1:将动态生成的属性注入(inject)属性值
解决方法的第一个选项有点丑陋,但我尝试过,它可以在http://less2css.org上使用。
因此,我尝试将动态创建的属性注入(inject)到另一个由您硬编码的属性的值中(我刚刚在此处给了一个随机的“供应商”名称
-inj
并将其分配为ect
值,但是您可能想使用一些有用的方法代替(如果您已经从所有供应商mixin中添加了元素).vendors(@property, @value, @pre: ect) {
-inj:~"@{pre}; -webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value}";
}
我们可以在一个示例上进行尝试-也许值得尝试的东西...让我们简短地尝试一下:(少):
.test-class{
.vendors(transform, matrix(1,0,0,1,20,20));
.vendors(transform-origin,"10px 10px");
}
CSS输出:.test-class {
-inj: ect; -webkit-transform: matrix(1, 0, 0, 1, 20, 20); -moz-transform: matrix(1, 0, 0, 1, 20, 20); -ms-transform: matrix(1, 0, 0, 1, 20, 20); -o-transform: matrix(1, 0, 0, 1, 20, 20); transform: matrix(1, 0, 0, 1, 20, 20);
-inj: ect; -webkit-transform-origin: 10px 10px; -moz-transform-origin: 10px 10px; -ms-transform-origin: 10px 10px; -o-transform-origin: 10px 10px; transform-origin: 10px 10px;
}
这似乎产生工作的CSS,但感觉kinnda错误=)解决方法#2:将动态生成的属性注入(inject)以下类的名称(最高v1.3.3)
因此,我对这个想法进行了更多尝试,并想到了一种不会产生不必要属性的方法。它将动态创建的属性注入(inject)到下一个类的名称中。让我告诉你我是如何工作的:
1)让我们定义一个通用的供应商混合(
@rest
参数稍后将用于排列多个供应商块).vendors(@property, @value, @rest:"") {
@inject:~"@{rest} -webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value};";
}
2)构造一个虚拟类/规则集,我们希望将供应商包含在其中,但是我们将其作为一个mixin,最后构造了下一个类welwel-因此,我们实际上制作了一个mixin,它将递归地构建两个或多个类。例如(使用与上述相同的示例),我们可以编写如下内容(注意在第二个@inject
调用中使用.vendor()
将两个供应商块绑定(bind)在一起):.test(@nextclass){
.vendors(transform, "matrix(2,0,0,2,20,20)");
.vendors(transform-origin,"10px 10px", @inject);
(~"{@{inject}} .@{nextclass}"){/*next class properties*/};
}
3)现在,我们将这个mixin包装到另一个类中以显示在CSS中:.this-class{
.test(next-class);
}
生成的 CSS 将包括以下内容:.this-class {
-webkit-transform: matrix(2, 0, 0, 2, 20, 20);
-moz-transform: matrix(2, 0, 0, 2, 20, 20);
-ms-transform: matrix(2, 0, 0, 2, 20, 20);
-o-transform: matrix(2, 0, 0, 2, 20, 20);
transform: matrix(2, 0, 0, 2, 20, 20);
-webkit-transform-origin: 10px 10px;
-moz-transform-origin: 10px 10px;
-ms-transform-origin: 10px 10px;
-o-transform-origin: 10px 10px;
transform-origin: 10px 10px;
}
.next-class {
/*next class properties*/
}
输出将仅在一行中。编辑:要获得更好的格式设置,可以包括
"\n"
和"\t"
的javascript插值,请参阅下面评论中的Scott建议。这样,您现在可以使用供应商mixin链接多个类,而无需任何不必要的属性。
解决方法#3:使用递归将动态生成的属性注入(inject)到以下类(v1.4.0)的名称中
我正在添加此原因,因为Scott在其中一项评论中指出,版本1.4所进行的更改将不允许解决方法#2。但是,如果我们有足够的资源,我们可以克服这个问题。让我们看看上述解决方法有哪些问题并加以解决。
1)第一个问题是“不赞成使用
(~".@{index}") { ...
选择器插值”,因此我们需要在单独的步骤中进行字符串插值。实现这一点足以从上方注入(inject)单个.vendors
mixin。最少:(使用Scott的换行符建议):
@nl: `"\n\t"`;
.vendors(@property, @value) {
@inject:~"@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
}
.test(@nextclass){
.vendors(transform, "matrix(2,0,0,2,20,20)");
@inj: ~"{@{inject}`'\n'`} `'\n'`.@{nextclass}";
@{inj} {/*next class properties*/}
}
.this-class{
.test(next-class);
}
CSS输出:.this-class {
-webkit-transform: matrix(2,0,0,2,20,20);
-moz-transform: matrix(2,0,0,2,20,20);
-ms-transform: matrix(2,0,0,2,20,20);
-o-transform: matrix(2,0,0,2,20,20);
transform: matrix(2,0,0,2,20,20);
}
.next-class {
/*next class properties*/
}
2)第二个问题是“mixin中的变量不再'泄漏'到其调用范围内”,但我在1.4.0 beta中注意到,如果仅在mixin中引入变量,则仍可以调用它从包含的规则集中开始,只需稍作递归,就可以构造.vendors
块,并在最后一步中将它们分配给新变量,然后将其用于注入(inject)。我也很兴奋,并使用了此less版本中引入的新extract()
函数。使用@i
变量,我们指定递归级别(要注入(inject)的供应商块数)。(少):
@nl: `"\n\t"`;
.multi(@props,@vals,1,@inj) {
@property: extract(@props, 1);
@value: extract(@vals, 1);
@inject:~"@{inj}@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
}
.multi(@props,@vals,@i,@inj:"") when (@i > 0) {
@property: extract(@props, @i);
@value: extract(@vals, @i);
@injnext:~"@{inj}@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
.multi(@props,@vals,(@i - 1),@injnext);
}
@properties: "transform-origin" "transform";
@values: "10px 10px" "matrix(2,0,0,2,20,20)";
// string of other properties you want to include in the same class
@p: ~"@{nl}width:20px; @{nl}height:12px; @{nl}background-color:#000;";
.this-class {
.multi(@properties,@values,2,@p);
@inj: ~"{@{inject}`'\n'`} `'\n'`.next-class ";
@{inj} {/**/}
}
CSS输出:.this-class {
width:20px;
height:12px;
background-color:#000;
-webkit-transform: matrix(2, 0, 0, 2, 20, 20);
-moz-transform: matrix(2, 0, 0, 2, 20, 20);
-ms-transform: matrix(2, 0, 0, 2, 20, 20);
-o-transform: matrix(2, 0, 0, 2, 20, 20);
transform: matrix(2, 0, 0, 2, 20, 20);
-webkit-transform-origin: 10px 10px;
-moz-transform-origin: 10px 10px;
-ms-transform-origin: 10px 10px;
-o-transform-origin: 10px 10px;
transform-origin: 10px 10px;
}
.next-class {
/*next class properties*/
}
现在,在1.4.0 beta中,这对我来说效果很好,但是让我们看看 future 会怎样。
关于css - 在LESS中使用属性名称中的变量(动态属性/属性名称插值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14868042/