CSS嵌套:继承自谁?

3

这里有一个存在问题的代码片段:
https://jsfiddle.net/c2exs2f7/3/

如何使第二个“blue”和第一个实例相同(应该为color: white),而不改变HTML结构?

HTML

<div class="blue">
  <div class="content">
    <div class="label">blue</div>
    <div class="yellow">
      <div class="content">
        <div class="label">yellow</div>
        <div class="blue">
          <div class="content">
            <div class="label">blue</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

SCSS

// Skip until...

div {
  border-radius: .25em;
  padding: .5em;
  font-family: helvetica, sans-serif;
}

// ...here:

.blue {
  background-color: hsl(220,100%,50%);

  .content {
    color: white;
  }
}

.yellow {
  background-color: hsl(60,100%,50%);

  .content {
    color: hsl(0,0%,10%);
  }
}

编辑 #1 谢谢大家的快速回复!
我正在开发一个网格系统,其中我能够嵌套不同的网格系统(具有不同的CSS值)。


2
拥有一个jsfiddle是一个不错的补充,但你应该始终将重要部分与问题本身一起包含。一个问题(以及答案)应该始终是自包含的,因为外部链接可能会失效。 - t.niese
好的。谢谢!我对这个还很新 :) - michaelcssguy
5个回答

2
选择器 .yellow .content.blue .content 在这种情况下具有相同的特异性(20),因此样式表中后出现的选择器将覆盖第一个选择器,这是样式表层叠性质的结果。在这种情况下,选择器.yellow .content 覆盖了 .blue .content,这就是为什么嵌套的 .blue 元素是黑色的原因。
一个快速的解决方案是使用选择器 .blue .blue 来选择嵌套的 .blue 元素: 更新的示例
.blue,
.blue .blue {
    background-color: hsl(220,100%,50%);

    .content {
        color: white;
    }
}

一种可能更好的方法是仅选择直接的 .content 子元素,使用 子选择器, >

更新的示例

.blue {
    background-color: hsl(220,100%,50%);

    > .content {
        color: white;
    }
}

.yellow {
    background-color: hsl(60,100%,50%);

    > .content {
        color: hsl(0,0%,10%);
    }
}

根据您的评论,元素的排序/分层可能会有所不同。另一种解决方案是在 .blue/.yellow 元素上设置 color 属性,然后将子元素的 color 属性设置为 inherit

更新示例 - 这似乎适用于所有变体。

.blue {
    background-color: hsl(220,100%,50%);
    color: white;

    .content {
        color: inherit;
    }
}

.yellow {
    background-color: hsl(60,100%,50%);
    color: hsl(0,0%,10%);

    .content {
        color: inherit;
    }
}

我喜欢这种第一种方法,但如果HTML标记是“yellow> yellow> blue”:https://jsfiddle.net/jzbjd655/1/,它将无法工作。有没有更好的方法可以在不声明每个特定顺序混合蓝色和黄色的可能性的情况下实现这一点?使用子选择器的第二个示例对于这个简单的示例非常好,但我不确定我能否保证母亲和孩子之间不会有一些“层次结构”div。 - michaelcssguy
伟大的新解决方案。有没有类似的方法可以实现我的目标,而不必将.blue的颜色设置为白色?如果我有一个网格系统,你的这个解决方案就不会那么好了。在你的例子中,.blue和.yellow获得颜色是可以的。但如果在我的真实项目中,像“.row”这样的父元素获取“.column”宽度属性的值,那就不行了。 - michaelcssguy

1

请查看https://jsfiddle.net/c2exs2f7/4/

我所做的是仅强制子类 content 的继承,而不是整个后代。

在 SCSS 中应用直接子级运算符 > 使 .content div 仅考虑其直接父元素的颜色。

继续尝试嵌套更多的 DIV,您会发现它可以工作。


0

你做不到。至少不能通过继承实现。因为第二个蓝色块将从黄色块继承。所以如果您希望所有蓝色块始终具有白色字母,所有黄色块始终具有黑色字母。为什么不直接放置:

.blue { color: #fff; }
.yellow { color: hsl(0,0%,10%); }

而且你不需要使用“.content”包装器。


这是一个很好的想法。我的问题是,我的代码是网格系统的一些简化。 - michaelcssguy

0

由于最内层标签没有兄弟节点,您可以执行以下操作:

.blue .label:only-child {
  color: white;
}

:only-child CSS 伪类表示一个没有任何兄弟元素的元素。


0

我曾经遇到过这个问题,HTML嵌套结构不同,因此无法使用更具体的选择器,代码变得非常复杂且不易维护。

以下是我找到的解决方案:

https://jsfiddle.net/cg0u8v1s/

基本上,对于类名的系统化处理是关键的,这样您就可以可靠地使用CSS属性选择器(尽管我建议使用比“color-”更独特的命名约定,因为它太通用了)。

例如:

.color-blue {
  &,
  [class*="color-"] &,
  [class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
    background-color: blue;

    .content {
      color: skyblue;
    }
  }
}

.color-yellow {
  &,
  [class*="color-"] &,
  [class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
    background-color: yellow;

    .content {
      color: brown;
    }
  }
}

这将输出选择器,随着嵌套的加深变得更具体,而无需使用非DRY代码或必须使用!important。

CSS输出如下:

.color-blue,
[class*="color-"] .color-blue,
[class*="color-"] [class*="color-"] .color-blue {
  // code...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接