在LESS中使用属性名称中的variables(dynamic属性/属性名称插值)
我注意到在SASS写的inuit.css有一个.vendor混合:
@mixin vendor($property, $value...){ -webkit-#{$property}:$value; -moz-#{$property}:$value; -ms-#{$property}:$value; -o-#{$property}:$value; #{$property}:$value; }
有没有办法在LESS中复制一些奇怪的function,如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
就我而言,更less的还没有添加对dynamic插入的属性的支持,这已经在很多次以前讨论过,请参阅:
-
LESS CSS使用不同的前缀转义整个CSS规则?
-
通用`供应商`mixin
-
圆angular桌与LESS
所以通常这样做的方式是使用参数混合和模式匹配…所以它是一个多一点的硬编码…但不pipe怎样,属性和不同的供应商有时需要一些不同的参数格式,所以多一点控制是这样添加的。
解决方法#1:将dynamic生成的属性注入属性值
解决方法的第一个选项有点难看,但我尝试了它,它在http://less2css.org上工作; 。 所以,我尝试的是将dynamic创build的属性注入到您难以编码的另一个属性的值中(我只是给了一个随机的“供应商”名称-inj
here并为其赋值,但是您可能想要使用某种有用的相反,如果你已经添加了一个来自所有供应商的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:将dynamicaly生成的属性注入到以下类的名称(最多v1.3.3)
所以我多玩了一下这个想法……想到了一种不会产生不必要属性的方法。 它将dynamic创build的属性注入到下一个类的名称中。 让我告诉你我是如何工作的:
1)让我们定义一个通用的供应商混合( @rest
参数将用于排队多个供应商块以后)
.vendors(@property, @value, @rest:"") { @inject:~"@{rest} -webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value};"; }
2)构build一个我们希望包含供应商的虚拟类/规则集,但是我们把它作为一个混合体,最后构build下一个类aswe – 所以我们真正制作一个混合体,recursion地构build两个或更多的类。 例如(使用与上面相同的例子),我们可以这样写(注意在第二个.vendor()
调用中使用@inject
来将两个供应商块绑定在一起):
.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插值,请参阅下面评论斯科特的build议。
现在,您可以使用供应商mixin链接多个类,而不需要任何不必要的属性。
解决方法#3:使用recursion将dynamic生成的属性注入到以下类(v1.4.0)的名称中
我在添加这个原因,斯科特在其中一个评论中指出,1.4版本将带来的变化将不会允许解决方法#2。 但是如果我们有一点足智多谋,我们可以克服这个问题。 让我们看看以上解决方法的问题,并解决它们。
1)第一个问题是“ (~".@{index}") { ...
select器插值被弃用”,所以我们需要在一个单独的步骤中进行string插值。 实现这个就足以从上面注入一个.vendors
mixin。
LESS 🙁使用Scott的换行build议):
@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中的variables不再”泄漏“到它们的调用范围中”,但是我注意到在1.4.0 beta版中,如果一个variables只在mixin中引入,它仍然可以从包括规则集,所以只需要一点点recursion,就可以构build.vendors
块,并在最后一步将它们分配给一个新的variables,然后用于注入。 我也很兴奋,并且使用了这个版本less中引入的新的extract()
函数。 用variables@i
分配recursion级别(要注入的供应商块的数量)。
减:
@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.0testing版对我来说很好,但是让我们看看未来会带来什么。
我只是想补充一点,你可以使用'minus'作为一个propery的名字和parsing器将忽略它,但添加string的其余部分。 这样你就不会得到一个空的inject:;
或者注射。 这仍然是哈克,但嘿… 🙂
.prefix(@property, @value) { -:~";-webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value}"; }
例:
.prefix(transition, "all .2s, color 0s");
会输出:
-webkit-transition: all .2s, color 0; -moz-transition: all .2s, color 0; -ms-transition: all .2s, color 0; -o-transition: all .2s, color 0; transition: all .2s, color 0;