LESS CSS:嵌套时滥用 & 运算符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11537260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 04:31:49  来源:igfitidea点击:

LESS CSS: abusing the & Operator when nesting?

csscss-selectorsless

提问by Christoph

Less uses the &Operator to enhance the possibilities for nesting.

Less 使用&Operator 来增强嵌套可能性

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

which causes a substitution of the &with the parent selector and results in a concatentation of the actual selector right to the parent selector: .header .navigation.classinstead of the normal appending, which would result in .classbeing a decendant: .header .navigation .class.

这会导致&用父选择器替换 ,并导致实际选择器与父选择器的串联:.header .navigation.class而不是正常的附加,这将导致.class成为后代:.header .navigation .class

Now what also is possible is the following (see also here):

现在还有可能的是以下内容(另请参见此处):

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

which would result in the following: #some-id .header .navigation .footry here. The substition takes place and i have prependeda selector (#some-id) to my parent selector.

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

Besides the fact that I would never code this way, since this probably messes up your stylesheet in no time, my question:

除了我永远不会以这种方式编码的事实之外,因为这可能会立即弄乱您的样式表,我的问题是:

As this functionality is not documented, is it a feature or more likely a bug?
Which are possible side-effects?

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

采纳答案by ScottS

I also have been pondering this use further since we encountered it in that question you referenced. While I cannot answer definitively that this is a "bug" use for &(BoltClock seems to make a good argument that it is nota bug), I want to argue for the value of it (which argues it is not a bug from a logical standpoint).

自从我们在您提到的那个问题中遇到它以来,我也一直在进一步思考这种用法。虽然我无法明确回答这是一个“错误”用途&(BoltClock 似乎很好地论证了它不是错误),但我想论证它的价值(认为它不是逻辑上的错误)立场)。

However, before the logical argument, I did find another short, simple quote(in the "nested rules" section) that seems to indicate it is at least not unintended: "&represents the current selector parent." That's it. As BoltClock argues, whether prepending or appending seems irrelevant. All that was intended was that it be a placeholder for that "selector parent" that is current up to that point. The fact that it is always mentioned in conjunction with the "nesting" use of the language implies it is designed to designate the full selector string of the nest up to the point of the nest that it resides within. How that string is used (to pre- or append) would seem up to the coder.

然而,在逻辑论证之前,我确实找到了另一个简短的引用(在“嵌套规则”部分),它似乎表明它至少不是无意的:“&代表当前选择器父级。” 就是这样。正如 BoltClock 所说,前置或附加似乎无关紧要。所有的目的是它是当前到那个点的“选择器父级”的占位符。事实上,它总是与语言的“嵌套”使用一起被提及,这意味着它旨在指定嵌套的完整选择器字符串,直到它所在的嵌套点。如何使用该字符串(用于预先或附加)似乎取决于编码器。

Now, you mention (and previously mentioned) that you "would never code this way," and yet I find myself seeing what appears to be a very valuable use for this. Consider the following argument.

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

The HTML Setup for the Illustration

插图的 HTML 设置

Assume, for the sake of illustration, there is a dynamic setting of three possible classes ('light', 'medium', 'dark' themes) on the bodyelement that change the "look" of the site. We have two columns, and some various types of links we want to style (textLink, picLink, textWithIconLink) differently in each column for each theme.

为了说明起见,假设在body改变站点“外观”的元素上有三个可能的类(“浅”、“中”、“深”主题)的动态设置。我们有两列,以及一些不同类型的链接,我们希望在每个主题的每一列中对( textLink, picLink, textWithIconLink) 进行不同的样式设置。

<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>

Now the questions to ask are, just looking at the links, of the two following methods, which...

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

  1. Is less code in LESS
  2. Best organzies the code in LESS
  3. Outputs less code in CSS
  4. Best organizes the outputted CSS
  1. LESS 中的代码更少
  2. 最好在 LESS 中组织代码
  3. 在 CSS 中输出更少的代码
  4. 最好组织输出的 CSS

"Best" may be somewhat subjective. I'll let you weigh that evidence yourself from below.

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

Option #1 Typical Nesting

选项 #1 典型嵌套

LESS(approx. 99 lines of code)

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 Output(approx. 87 lines of output, organized by theme of course)

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);
}

Option #2 End Target Grouping

选项 #2 结束目标分组

I've named it "End Target Grouping," because that's really how I see using the &in this other way of adding parent selectors. One is now coding based off the final end target element that is actually being styled.

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

LESS(approx. 88 lines of code)

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(approx. 88 lines of output [due to one extra comment], organized by end target element; but notice, there is still a suborganization by theme because of the class structure)

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);
}

Concluding Thoughts

总结性思考

A few other considerations:

其他一些注意事项:

First, most of your theme colors (and possibly other themeing aspects) will be set up with variables, which can be grouped at the top of the LESS code by theme even using Option #2 above--so having the theme structure for the output CSS itself scattered in the code is not necessarily bad.

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

Second, any "standard" code for a type of element is defined above any theme code. My examples did not show this, but say all .textLinkelements had text-decoration: none;set. That would occur once under Option #2 without any further selector code, and would appear above all the theme changes below. For Option #1, I need to set up a new, unnested.textLinkselector (at least one other line of code) to apply it to all themed links, and that "base" code for the class will, again, be somewhere unrelated to where the rest of the code for the theme link info is.

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

Third, as a developer, if I am having issues with my picLinks(a specific type of element on my page), Option #2 makes it far easier to examine my code for the element I am having issues with, as all my code for all the themes is right in one spot.

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

Obviously, how one wants the final LESS and CSS organized is going to be a major factor in how one sees the value of this.My point here is to merely demonstrate that there is a very useful, logical reason to use the &in this way of adding parent level selectors to the &reference.

显然,人们希望最终的 LESS 和 CSS 的组织方式将成为人们如何看待其价值的一个主要因素。我在这里的观点只是为了证明&以这种方式使用 将父级选择器添加到&引用有一个非常有用的、合乎逻辑的理由。

回答by BoltClock

It's not abuse of the &combinator at all; you can place it anywherein a nested selector and it'll be substituted with whatever is above it (its so-called parent selector):

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

[The &combinator is] used when you want a nested selector to be concatenated to its parent selector, instead of acting as a descendant.

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

Notice that it says "concatenated"; it doesn't say you can only either prepend or append the parent selector to the nested selector. Concatenation doesn't work in any specific direction only.

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

Further, the word "descendant" has to do with the nature of nested selectors being treated as though they were linked by the descendant combinator by default. In no way does that inherently limit the use of &to descendants only, nor does it imply that the parent selector has to represent a parent or ancestor element in such a way that the nested selector may only be appended to it, and not prepended or even inserted into the middle of it.

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