在LESS中是否有可能将mixin嵌套在另一个中,以便仅当元素是具有后者mixin的元素的子元素时才调用前者?
我知道,令人困惑,这是一个简单的例子(不工作代码,只是概念):
LESS
.foo(@x) {
width: @x;
.foo(@y) {
width: @y/@x;
}
}
.a {
.foo(20px);
.b {
.foo(2);
}
}
输出CSS
.a {
width: 20px;
}
.a .b {
width: 10px;
}
当我执行此操作时,在.foo(2)
上调用.b
可以编译width: 2
。
这应该是这样的设计,还是我在语法上出错?另外,我是从一个完全错误的角度来解决这个问题,也许还有一个更简单的解决方案我不考虑?
好的,显然这是用最新版本的LESS修复的,但我想要实现的,比我上面给出的最小例子稍微复杂一点。
基本上我想要发生的是,每个.foo
是.foo
mixin的另一个元素的子节点,它将使用其父变量进行计算,因此,理想情况下
LESS
.foo(@x) {
width: @x;
.foo(@y) {
width: (@x/@y);
}
}
.a {
.foo(100px);
.b {
.foo(2px);
.c {
.foo(5px);
/* ...and so on */
}
}
}
输出CSS
.a {
width: 100px;
}
.a .b {
width: 50px;
}
.a .b .c {
width: 10px;
}
我得到的是:
.a .b .c {
width: 50px;
}
我尝试按如下方式修改LESS:
.foo(@x) {
width: @x;
.foo(@y) {
@x: (@x/@y)
width: (@x);
}
}
但是我收到了递归变量定义的语法错误。显然LESS不允许定义如下:
@a: 1;
@a: (@a+1);
答案 0 :(得分:5)
我认为这里的主要问题是@y/@x
。
试试@x/@y
,它应该提供更多预期的东西; - )
由于嵌套的mixins在不同的实现中被解释为不同,我现在将答案分为两部分:
否则我认为上面的代码实际上在less2css.org上做了你想要的。 正如LESS 1.4中的概念一样,您需要小心数学,因为默认情况下它需要在括号中。
如果你现在只是在非现行规则上调用这样的mixin,比如
.b { 包含.foo(@y); }
您需要将输入变量中的单位或广告unit()
用于您的mixin,否则您只会获得您输入的数字,例如2:
.foo(@x) {
width: unit(@x,px);
.foo(@y) {
width: (@x/@y);
}
}
.a {
.foo(20px);
.b{
.foo(2);
}
}
.c {
.foo(2);
}
将输出 CSS:
.a {
width: 20px;
}
.a .b {
width: 10px;
}
.c {
width: 2px;
}
你可以变得更加漂亮,并且如果子类中的属性将pixles作为一个单元,请与守卫核对,这样你也可以在没有传递因子的地方嵌套类:
.foo(@x) {
width: @x;
.foo(@y) when (ispixel(@y)) {
width: @y;
}
.foo(@y) when not (ispixel(@y)) {
width: (@x/@y);
}
}
然而,测试这个嵌套的mixin解决方案似乎只适用于less2css.org,但不适用于jsbin.com,lesstester.com和其他一些服务[需要用{{1来调用嵌套(第二)级别的mixin)从mixin中应用第二级样式。
所以我提出了一种替代方法,我测试了它,并且它似乎适用于所有提到的页面,使用less-css编译器,其中> 1.2。
.foo .too
防护的解决方案应该适用于大多数LESS> 1.2安装您可以构建两个mixin,而不是嵌套的mixin,它们基于警卫检查像素为单位。
ispixel
以像素为单位=>返回@x
并将width:@x;
分配给变量@x
@width
不在像素中=>返回@x
(注意: width:@width/@x;
需要事先通过首先使用@width
中的@x
调用mixin来分配示例 LESS:
px
输出 CSS :
.foo(@x) when (ispixel(@x)) {
width:@x;
@width:@x;
}
.foo(@x) when not (ispixel(@x)) {
width: (@width/@x);
}
.a, .b {
background-color: #ddd;
height: 100px;
}
.a {
.foo(100px);
.b {
background-color: red;
.foo(2);
}
}
与您的方法不同,但可能更直接一点,似乎运作良好。
因为你不想区分输入单位和没有单位的输入,我只能想到调用两个参数mixin ,其中一个参数用于基数({{ 1}}在你的情况下)和第二个作为一个默认为1的因子。这你可以现在递归调用你想要的次数。
<强> LESS:强>
.a, .b {
background-color: #ddd;
height: 100px;
}
.a {
width: 100px;
}
.a .b {
background-color: red;
width: 50px;
}
输出 CSS:
width
所以现在输入的单位并不重要,因为你可以在mixin中为输出分配所需的单位。当你调用mixin时,它会覆盖当前作用域的.foo(@x,@y:1){
width:unit(@parent,px);
@parent:(@x/@y);
}
.a {
.foo(100px);
.b{
.foo(@parent,2px);
.c{
.foo(@parent,5px);
.d{
.foo(@parent,0.05);
}
}
}
}
变量,然后继承到嵌套规则,在再次调用mixin时可以将其用作宽度参数.a {
width: 100px;
}
.a .b {
width: 50px;
}
.a .b .c {
width: 10px;
}
.a .b .c .d {
width: 200px;
}
。这应该会给你想要的结果。