【问题标题】:LESS CSS: abusing the & Operator when nesting?LESS CSS:嵌套时滥用 & 运算符?
【发布时间】:2012-07-17 05:53:54
【问题描述】:

Less 使用& 运算符来增强possibilities for nesting

.header        { color: black;
  .navigation  { font-size: 12px;
    &.class    { text-decoration: none }
  }
}

这会导致& 被父选择器替换,并导致将实际选择器权限连接到父选择器:.header .navigation.class 而不是正常的附加,这将导致.class 成为后代:.header .navigation .class.

现在还可以进行以下操作 (see also here):

.header        { color: black;
  .navigation  { font-size: 12px;
    #some-id & .foo   { text-decoration: none }
  }
}

这将导致以下结果:#some-id .header .navigation .foo try here 。发生了替换,我在父选择器中预先添加了一个选择器 (#some-id)。

除了我永远不会这样编码,因为这可能很快就会弄乱你的样式表,我的问题:

由于没有记录此功能,它是一个功能还是更可能是一个错误?
哪些是可能的副作用?

【问题讨论】:

  • 不懂你,“#some-id &”有什么意义?错误的代码肯定会产生错误的编译/转换结果,而且不可能记录所有错误行为。
  • @DenisAgarev 您对 LESS 有经验吗?如果没有,请阅读不要写...
  • 经验丰富,但忘了这个语法,对不起。也许这样的编码对于编辑一些现有的大型 css 文件很有用,但我认为通常使用这种替换可能是危险的
  • 这是故意行为。在less.js 源中搜索'&' 可以清楚地了解这一点。 LESS 文档并不出色,这很可能是没有文档记录的原因。可能的副作用包括:在选择器中间使用 & 可能会造成混淆。
  • 这是文档:lesscss.org/features/#parent-selectors-feature,奇怪的是它只提到了前置:)

标签: css css-selectors less


【解决方案1】:

自从我们遇到in that question you referenced 以来,我也一直在进一步思考这个用途。虽然我无法明确回答这是 & 的“错误”用途(BoltClock 似乎提出了一个很好的论点,即它不是错误),但我想为它的价值争论(从逻辑的角度来看,这不是一个错误)。

但是,在逻辑参数之前,我确实找到了another short, simple quote(在“嵌套规则”部分中),这似乎表明它至少不是无意的:“& 表示当前选择器父级。”而已。正如 BoltClock 所说,前置或附加似乎无关紧要。所有的意图是它是那个“选择器父级”的占位符,直到那个时候。它总是与语言的“嵌套”使用一起提到的事实意味着它旨在指定嵌套的完整选择器字符串,直到它所在的嵌套点。如何使用该字符串(预先或附加)似乎取决于编码器。

现在,您提到(和之前提到的)您“永远不会以这种方式编码”,但我发现自己看到了似乎非常有价值的用途。考虑以下论点。

插图的 HTML 设置

假设,为了说明起见,body 元素上存在三个可能的类('light'、'medium'、'dark'主题)的动态设置,它们改变了网站的“外观”。我们有 两列,以及我们希望在每个主题的每一列中以不同方式设置样式的一些不同类型的链接(textLinkpicLinktextWithIconLink)。

<body class="light">
  <div class="leftCol">
     <a class="textLink"></a>
     <a class="picLink"></a>
     <a class="textWithIconLink"></a>
  </div>
  <div class="rightCol">
     <a class="textLink"></a>
     <a class="picLink"></a>
     <a class="textWithIconLink"></a>
  </div>
</body>

现在要问的问题是,只需查看链接,以下两种方法...

  1. LESS 中的代码更少
  2. 最好将 LESS 中的代码组织起来
  3. 在 CSS 中输出更少的代码
  4. 最好地组织输出的 CSS

“最佳”可能有些主观。我会让你自己从下面权衡这些证据。

选项 #1 典型嵌套

LESS(大约 99 行代码)

/*Light Color Theme */
    .light {
      .leftCol {
        .textLink {
          color: fooL1;
          &:hover { color: barL1;}
        } 
        .picLink {
          background-image: url(/fooL1.jpg);
          &:hover { background-image: url(/barL1.jpg);}
        }
        .textWithIconLink {
          color: fooL2;
          background-image: url(/fooL2.jpg);
          &:hover { color: barL2; background-image: url(/barL2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooL3;
          &:hover { color: barL3;}
        } 
        .picLink {
          background-image: url(/fooL3.jpg);
          &:hover { background-image: url(/barL3.jpg);}
        }
        .textWithIconLink {
          color: fooL4;
          background-image: url(/fooL4.jpg);
          &:hover { color: barL4; background-image: url(/barL4.jpg);}
        }   
      }
    }
/*Medium Color Theme */
    .medium {
      .leftCol {
        .textLink {
          color: fooM1;
          &:hover { color: barM1;}
        } 
        .picLink {
          background-image: url(/fooM1.jpg);
          &:hover { background-image: url(/barM1.jpg);}
        }
        .textWithIconLink {
          color: fooM2;
          background-image: url(/fooM2.jpg);
          &:hover { color: barM2; background-image: url(/barM2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooM3;
          &:hover { color: barM3;}
        } 
        .picLink {
          background-image: url(/fooM3.jpg);
          &:hover { background-image: url(/barM3.jpg);}
        }
        .textWithIconLink {
          color: fooM4;
          background-image: url(/fooM4.jpg);
          &:hover { color: barM4; background-image: url(/barM4.jpg);}
        }   
      }
    }
/*Dark Color Theme */
    .dark {
      .leftCol {
        .textLink {
          color: fooD1;
          &:hover { color: barD1;}
        } 
        .picLink {
          background-image: url(/fooD1.jpg);
          &:hover { background-image: url(/barD1.jpg);}
        }
        .textWithIconLink {
          color: fooD2;
          background-image: url(/fooD2.jpg);
          &:hover { color: barD2; background-image: url(/barD2.jpg);}
        }   
      }
      .rightCol {
        .textLink {
          color: fooD3;
          &:hover { color: barD3;}
        } 
        .picLink {
          background-image: url(/fooD3.jpg);
          &:hover { background-image: url(/barD3.jpg);}
        }
        .textWithIconLink {
          color: fooD4;
          background-image: url(/fooD4.jpg);
          &:hover { color: barD4; background-image: url(/barD4.jpg);}
        }   
      }
    }

CSS 输出(大约 87 行输出,当然按主题组织)

 /*Light Color Theme */
.light .leftCol .textLink { color:fooL1; }
.light .leftCol .textLink:hover { color:barL1; }
.light .leftCol .picLink { background-image:url(/fooL1.jpg); }
.light .leftCol .picLink:hover { background-image:url(/barL1.jpg); }
.light .leftCol .textWithIconLink {
  color:fooL2;
  background-image:url(/fooL2.jpg);
}
.light .leftCol .textWithIconLink:hover {
  color:barL2;
  background-image:url(/barL2.jpg);
}
.light .rightCol .textLink { color:fooL3; }
.light .rightCol .textLink:hover { color:barL3; }
.light .rightCol .picLink { background-image:url(/fooL3.jpg); }
.light .rightCol .picLink:hover { background-image:url(/barL3.jpg); }
.light .rightCol .textWithIconLink {
  color:fooL4;
  background-image:url(/fooL4.jpg);
}
.light .rightCol .textWithIconLink:hover {
  color:barL4;
  background-image:url(/barL4.jpg);
}
/*Medium Color Theme */
.medium .leftCol .textLink { color:fooM1; }
.medium .leftCol .textLink:hover { color:barM1; }
.medium .leftCol .picLink { background-image:url(/fooM1.jpg); }
.medium .leftCol .picLink:hover { background-image:url(/barM1.jpg); }
.medium .leftCol .textWithIconLink {
  color:fooM2;
  background-image:url(/fooM2.jpg);
}
.medium .leftCol .textWithIconLink:hover {
  color:barM2;
  background-image:url(/barM2.jpg);
}
.medium .rightCol .textLink { color:fooM3; }
.medium .rightCol .textLink:hover { color:barM3; }
.medium .rightCol .picLink { background-image:url(/fooM3.jpg); }
.medium .rightCol .picLink:hover { background-image:url(/barM3.jpg); }
.medium .rightCol .textWithIconLink {
  color:fooM4;
  background-image:url(/fooM4.jpg);
}
.medium .rightCol .textWithIconLink:hover {
  color:barM4;
  background-image:url(/barM4.jpg);
}
/*Dark Color Theme */
.dark .leftCol .textLink { color:fooD1; }
.dark .leftCol .textLink:hover { color:barD1; }
.dark .leftCol .picLink { background-image:url(/fooD1.jpg); }
.dark .leftCol .picLink:hover { background-image:url(/barD1.jpg); }
.dark .leftCol .textWithIconLink {
  color:fooD2;
  background-image:url(/fooD2.jpg);
}
.dark .leftCol .textWithIconLink:hover {
  color:barD2;
  background-image:url(/barD2.jpg);
}
.dark .rightCol .textLink { color:fooD3; }
.dark .rightCol .textLink:hover { color:barD3; }
.dark .rightCol .picLink { background-image:url(/fooD3.jpg); }
.dark .rightCol .picLink:hover { background-image:url(/barD3.jpg); }
.dark .rightCol .textWithIconLink {
  color:fooD4;
  background-image:url(/fooD4.jpg);
}
.dark .rightCol .textWithIconLink:hover {
  color:barD4;
  background-image:url(/barD4.jpg);
}

选项 #2 结束目标分组

我将其命名为“结束目标分组”,因为这就是我真正看到的以这种添加父选择器的其他方式使用 &amp; 的方式。现在一个是根据实际设置样式的最终目标元素进行编码。

LESS(大约 88 行代码)

/*Links */
/*Text  Links*/
.textLink {
  .light .leftCol &  {
      color: fooL1;
      &:hover { color: barL1;}
    }      
  .light .rightCol &  {
      color: fooL3;
      &:hover { color: barL3;}
    } 
  .medium .leftCol &  {
      color: fooM1;
      &:hover { color: barM1;}
    } 
  .medium .rightCol &  {
      color: fooM3;
      &:hover { color: barM3;}
    } 
  .dark .leftCol &  {
      color: fooD1;
      &:hover { color: barD1;}
    } 
  .dark .rightCol &  {
      color: fooD3;
      &:hover { color: barD3;}
    } 
}
/*Picture Links */
.picLink {
  .light .leftCol &  {
      background-image: url(/fooL1.jpg);
      &:hover { background-image: url(/barL1.jpg);}
    } 
  .light .rightCol &  {
      background-image: url(/fooL3.jpg);
      &:hover { background-image: url(/barL3.jpg);}
    } 
  .medium .leftCol &  {
      background-image: url(/fooM1.jpg);
      &:hover { background-image: url(/barM1.jpg);}
    } 
  .medium .rightCol &  {
      background-image: url(/fooM3.jpg);
      &:hover { background-image: url(/barM3.jpg);}
    } 
  .dark .leftCol &  {
      background-image: url(/fooD1.jpg);
      &:hover { background-image: url(/barD1.jpg);}
    } 
  .dark .rightCol &  {
      background-image: url(/fooD3.jpg);
      &:hover { background-image: url(/barD3.jpg);}
    } 
}
/*Text with Icon Links */
.textWithIconLink {
  .light .leftCol &  {
      color: fooL2;
      background-image: url(/fooL1.jpg);
      &:hover { color: barL2; background-image: url(/barL1.jpg);}
    } 
  .light .rightCol &  {
      color: fooL4;
      background-image: url(/fooL3.jpg);
      &:hover { color: barL4;  background-image: url(/barL3.jpg);}
    } 
  .medium .leftCol &  {
      color: fooM2;
      background-image: url(/fooM1.jpg);
      &:hover { color: barM2; background-image: url(/barM1.jpg);}
    } 
  .medium .rightCol &  {
     color: fooM4;
      background-image: url(/fooM3.jpg);
      &:hover { color: barM4; background-image: url(/barM3.jpg);}
    } 
  .dark .leftCol &  {
     color: fooD2;
      background-image: url(/fooD1.jpg);
      &:hover { color: barD2; background-image: url(/barD1.jpg);}
    } 
  .dark .rightCol &  {
      color: fooD4;
      background-image: url(/fooD3.jpg);
      &:hover { color: barD4; background-image: url(/barD3.jpg);}
    } 
}

CSS(大约 88 行输出[由于一个额外的注释],按最终目标元素组织;但请注意,由于类结构,仍有按主题进行子组织)

/*Links*/
/*Text  Links*/
.light .leftCol .textLink { color:fooL1; }
.light .leftCol .textLink:hover { color:barL1; }
.light .rightCol .textLink { color:fooL3; }
.light .rightCol .textLink:hover { color:barL3; }
.medium .leftCol .textLink { color:fooM1; }
.medium .leftCol .textLink:hover { color:barM1; }
.medium .rightCol .textLink { color:fooM3; }
.medium .rightCol .textLink:hover { color:barM3; }
.dark .leftCol .textLink { color:fooD1; }
.dark .leftCol .textLink:hover { color:barD1; }
.dark .rightCol .textLink { color:fooD3; }
.dark .rightCol .textLink:hover { color:barD3; }
/*Picture Links */
.light .leftCol .picLink { background-image:url(/fooL1.jpg); }
.light .leftCol .picLink:hover { background-image:url(/barL1.jpg); }
.light .rightCol .picLink { background-image:url(/fooL3.jpg); }
.light .rightCol .picLink:hover { background-image:url(/barL3.jpg); }
.medium .leftCol .picLink { background-image:url(/fooM1.jpg); }
.medium .leftCol .picLink:hover { background-image:url(/barM1.jpg); }
.medium .rightCol .picLink { background-image:url(/fooM3.jpg); }
.medium .rightCol .picLink:hover { background-image:url(/barM3.jpg); }
.dark .leftCol .picLink { background-image:url(/fooD1.jpg); }
.dark .leftCol .picLink:hover { background-image:url(/barD1.jpg); }
.dark .rightCol .picLink { background-image:url(/fooD3.jpg); }
.dark .rightCol .picLink:hover { background-image:url(/barD3.jpg); }
/*Text with Icon Links */
.light .leftCol .textWithIconLink {
  color:fooL2;
  background-image:url(/fooL1.jpg);
}
.light .leftCol .textWithIconLink:hover {
  color:barL2;
  background-image:url(/barL1.jpg);
}
.light .rightCol .textWithIconLink {
  color:fooL4;
  background-image:url(/fooL3.jpg);
}
.light .rightCol .textWithIconLink:hover {
  color:barL4;
  background-image:url(/barL3.jpg);
}
.medium .leftCol .textWithIconLink {
  color:fooM2;
  background-image:url(/fooM1.jpg);
}
.medium .leftCol .textWithIconLink:hover {
  color:barM2;
  background-image:url(/barM1.jpg);
}
.medium .rightCol .textWithIconLink {
  color:fooM4;
  background-image:url(/fooM3.jpg);
}
.medium .rightCol .textWithIconLink:hover {
  color:barM4;
  background-image:url(/barM3.jpg);
}
.dark .leftCol .textWithIconLink {
  color:fooD2;
  background-image:url(/fooD1.jpg);
}
.dark .leftCol .textWithIconLink:hover {
  color:barD2;
  background-image:url(/barD1.jpg);
}
.dark .rightCol .textWithIconLink {
  color:fooD4;
  background-image:url(/fooD3.jpg);
}
.dark .rightCol .textWithIconLink:hover {
  color:barD4;
  background-image:url(/barD3.jpg);
}

结论性想法

其他一些注意事项:

首先,您的大多数主题颜色(可能还有其他主题方面)将使用变量进行设置,即使使用上面的选项 #2,也可以按主题将其分组在 LESS 代码的顶部——因此具有主题结构对于散落在代码中的输出 CSS 本身并不一定不好。

其次,任何一种元素的“标准”代码都定义在任何主题代码之上。我的示例没有显示这一点,但说所有.textLink 元素都设置了text-decoration: none;。这将在选项 #2 下发生一次,无需任何进一步的选择器代码,并将出现在下面所有主题更改的上方。对于选项 #1,我需要设置一个新的 unnested .textLink 选择器(至少另外一行代码)以将其应用于所有主题链接,以及类将再次与主题链接信息的其余代码所在的位置无关。

第三,作为开发人员,如果我的 picLinks(我页面上的一种特定类型的元素)有问题,选项 #2 可以更轻松地检查我遇到问题的元素的代码,因为我所有主题的所有代码都在一个位置。

很明显,一个人希望最终的 LESS 和 CSS 如何组织将是人们如何看待它的价值的一个主要因素。我的意思是仅仅证明使用&amp; 以将父级选择器添加到&amp; 引用的这种方式有一个非常有用且合乎逻辑的理由。

【讨论】:

  • 啊……“占位符”是我一直在逃避的那个词。 (实际上,在我无法真正集中注意力的时候,我已经在我的 iPhone 上写下了这个答案……当然,我现在好多了!)
  • @BoltClock--很高兴我能读懂你的潜意识想法。现在,如果我能了解您其余的 css 知识...
  • 感谢您的详细帖子。我真的很感激。然而我想解释我的陈述“永远不会这样编码”。试想一个 500-1000 行的文件。大型项目应该没问题。现在你想调试你的 css - 它被缩小了。如果没有这种“滥用”用法,则选择器#test .foo .bar .hello 由于嵌套的限制可能只有一个位置。通过这种“滥用”使用,您无法确定在哪个嵌套级别查找规则,因为 css-selector 可能位于任何地方。
  • @Christoph--首先,我不尝试调试缩小的代码,而是调试源代码。但我承认这并不总是可能的。但是,第二,如果按照我所展示的那样使用,您的选择器路径仍然只有“一个地方”:在代码的.hello“结束目标”部分下。换句话说,我建议的用途是一种反向嵌套。所有直接影响.hello 的代码都放在一起。我认为如果在某个中点使用&amp;,可能会出现麻烦。所以#test .foo [&amp; = .bar] .hello 您现在将父母和孩子一起添加。
【解决方案2】:

这根本不是&amp; 组合子的滥用;你可以将它任何地方放在一个嵌套选择器中,它会被它上面的任何东西(它所谓的父选择器)替换:

[&amp; 组合器用于] 当您希望将嵌套选择器连接到其父选择器而不是充当后代时。

注意它说的是“连接”;它并不是说您只能将父选择器添加或附加到嵌套选择器。连接仅在任何特定方向上都不起作用。

此外,“后代”一词与嵌套选择器的性质有关,它们被视为默认情况下由后代组合器链接。这绝不会固有地将 &amp; 的使用仅限于后代,也不意味着父选择器必须以嵌套选择器只能附加到它的方式表示父或祖先元素,而不是前置甚至插入到它的中间。

【讨论】:

  • 我知道 如何 工作以及为什么(这是一个简单的替代),但我想知道这是否是有意的,以及这在多大程度上有意义或没有意义。这是一个相当理论的问题。
  • 如果不是有意的,文档可能会这样说。这里很清楚它是预期的功能。
  • 好吧,我认为您不明白我的意思...文档指出,这用于将其他类,伪元素/类连接到最近的选择器。但是,它没有被记录用于在嵌套树中某处路径的开头添加额外的选择器。
  • 这并不是说你只能附加选择器。我已经编辑了我的答案。
  • 再次阅读我的编辑,尤其是我添加的引用下方的段落。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 2011-10-20
  • 2012-03-11
  • 1970-01-01
  • 2023-02-24
  • 2011-04-30
  • 2011-10-29
相关资源
最近更新 更多