在 LESS 中生成选择器列表

Posted

技术标签:

【中文标题】在 LESS 中生成选择器列表【英文标题】:Generating selector lists in LESS 【发布时间】:2013-12-13 22:04:22 【问题描述】:

现场演示:http://codepen.io/KenPowers/pen/Ddfqh

考虑以下 LESS 代码:

// Hide all list items by default and make internal labels have pointer cursors
li 
  display: none;
  label 
    cursor: pointer;
  


// This function generates selectors and corresponding css
.gen (@tag) 
  @sel: ~"#@tag:checked";
  @sel 
    & ~ ul > li[data-index~=@tag] 
      display: list-item;
    
    & ~ ul > li > label[for=@tag] 
      color: red;
    
  


// Generate required selectors and css
.gen("foo");
.gen("bar");
.gen("baz");

它会生成以下 CSS:

li 
  display: none;

li label 
  cursor: pointer;

#foo:checked ~ ul > li[data-index~="foo"] 
  display: list-item;

#foo:checked ~ ul > li > label[for="foo"] 
  color: red;

#bar:checked ~ ul > li[data-index~="bar"] 
  display: list-item;

#bar:checked ~ ul > li > label[for="bar"] 
  color: red;

#baz:checked ~ ul > li[data-index~="baz"] 
  display: list-item;

#baz:checked ~ ul > li > label[for="baz"] 
  color: red;

但是,压缩程度更高的输出可能如下所示:

li 
  display: none;

li label 
  cursor: pointer;

#foo:checked ~ ul > li[data-index~="foo"],
#bar:checked ~ ul > li[data-index~="bar"],
#baz:checked ~ ul > li[data-index~="baz"] 
  display: list-item;

#foo:checked ~ ul > li > label[for="foo"],
#bar:checked ~ ul > li > label[for="bar"],
#baz:checked ~ ul > li > label[for="baz"] 
  color: red;

有没有办法可以修改原始 LESS 以生成第二个 CSS 列表?

【问题讨论】:

【参考方案1】:

在 Less 1.4.0+ 中,您可以 :extend 占位符类:

.dp-list-item 
  display: list-item;

.label-color 
  color: red;


// This function generates selectors and corresponding css
.gen (@tag) 
  @sel: ~"#@tag:checked ~ ul > li";
  @sel 
    &[data-index~=@tag]:extend(.dp-list-item)
    & > label[for=@tag]:extend(.label-color)
  


// Generate required selectors and css
.gen("foo");
.gen("bar");
.gen("baz");

Forked pen

生成的 CSS:

.dp-list-item,
#foo:checked ~ ul > li[data-index~="foo"],
#bar:checked ~ ul > li[data-index~="bar"],
#baz:checked ~ ul > li[data-index~="baz"] 
  display: list-item;

.label-color,
#foo:checked ~ ul > li > label[for="foo"],
#bar:checked ~ ul > li > label[for="bar"],
#baz:checked ~ ul > li > label[for="baz"] 
  color: red;

如您所见,唯一的缺点是我用作占位符的两个类都将在生成的 CSS 中。我相信在 Less 实现类似于 Sass 的 placeholder selectors 之前,这是无法解决的。

ps。为简洁起见,我省略了不属于 mixin 的全局 li 规则。


根据 OP 请求,这是一个等效的 Sass(使用 .scss 语法):

//placeholder selectors
%dp-list-item 
  display: list-item;

%label-color 
  color: red;


// This function generates selectors and corresponding css
@mixin gen($tag) 
  ##$tag:checked ~ ul > li 
    &[data-index~=#$tag] 
      @extend %dp-list-item;
    
    & > label[for=#$tag] 
      @extend %label-color;
    
  


// Generate required selectors and css
@each $item in (foo bar baz) 
  @include gen($item);

Demo

生成的 CSS:

#foo:checked ~ ul > li[data-index~=foo], #bar:checked ~ ul > li[data-index~=bar], #baz:checked ~ ul > li[data-index~=baz] 
  display: list-item;


#foo:checked ~ ul > li > label[for=foo], #bar:checked ~ ul > li > label[for=bar], #baz:checked ~ ul > li > label[for=baz] 
  color: red;

您可以看到,与 Less 相比,Sass 的语法相当冗长。 Sass 还有一些不错的功能,例如我在上面的示例中应用的control directives 和出色的interpolation。

【讨论】:

假设我想使用 SASS,您愿意提供使用占位符选择器的等效代码吗? @KPthunder 当然,添加了一个 Sass 示例。 =]

以上是关于在 LESS 中生成选择器列表的主要内容,如果未能解决你的问题,请参考以下文章

Less一些选择器

嵌套选择器性能影响和 LESS

在 LESS 中扩展嵌套选择器

在 LESS CSS 中使用通用选择器作为 mixin

如何在 Less 中将两个变量连接为选择器

LESS:扩展先前定义的嵌套选择器