首页 > 解决方案 > 选择一个类的所有后代,除了另一个类中的后代(反之亦然)

问题描述

我想针对某个特定的所有 后代段落class,同时忽略第一个内部的另一个的所有 后代段落class(无论哪个类在哪个类中,这都应该有效)。为此,我必须使用 4 个选择器,如下所示:

* {
  margin: 0.2em 0;
  width: fit-content;
}

div {
  margin-left: 1em
}

/* == 4 selectors to achieve desired effect = */

.orange p {
  background: orange;
}

.cyan .orange p {
  background: orange;
}

.cyan p {
  background: cyan;
}

.orange .cyan p {
  background: cyan;
}
<div class="orange">
        <p>Orange</p>
        <div>
          <p>Orange</p>
          <div>
            <p>Orange</p>
            <div class="cyan">
              <p>Cyan</p>
              <div>
                <p>Cyan</p>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="cyan">
        <p>Cyan</p>
        <div>
          <p>Cyan</p>
          <div>
            <p>Cyan</p>
            <div class="orange">
              <p>Orange</p>
              <div>
                <p>Orange</p>
              </div>
            </div>
          </div>
        </div>
      </div>

问题是:这可以仅使用两个选择器来实现吗?[这两个选择器的顺序应该可以在不改变效果的情况下改变。]

我尝试过像这样的选择器:

.orange:not(.cyan) p {
  background: orange;
}

.cyan:not(.orange) p {
  background: cyan;
}

但它并没有很好地针对最后一个,因为它继承了第一个的风格。我正在寻找两个匹配这些情况的选择器,在样式表中没有任何特定的顺序。

标签: htmlcsscss-selectors

解决方案


这是一个带有 CSS 变量的简单解决方案。检查以下问题以获取更多详细信息:CSS scoped custom property ignored when used to calculate variable in external scope

* {
  margin: 0.2em 0;
  width: fit-content;
}

div {
  margin-left: 1em
}

p {
  background: var(--c);
}
.cyan {
  --c:cyan;
}
.orange {
  --c:orange;
}
<div class="orange">
  <p>Orange</p>
  <div>
    <p>Orange</p>
    <div>
      <p>Orange</p>
      <div class="cyan">
        <p>Cyan</p>
        <div>
          <p>Cyan</p>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="cyan">
  <p>Cyan</p>
  <div>
    <p>Cyan</p>
    <div>
      <p>Cyan</p>
      <div class="orange">
        <p>Orange</p>
        <div>
          <p>Orange</p>
        </div>
      </div>
    </div>
  </div>
</div>

您可以将其缩放为任意数量的颜色,因为每种颜色只需要一个选择器,并且顺序无关紧要:

* {
  margin: 0.2em 0;
  width: fit-content;
}

div {
  margin-left: 1em
}

p {
  background: var(--c);
}
.cyan {
  --c:cyan;
}
.orange {
  --c:orange;
}
.blue {
  --c:lightblue;
}
<div class="orange">
  <p>Orange</p>
  <div>
    <p>Orange</p>
    <div>
      <p>Orange</p>
      <div class="cyan">
        <p>Cyan</p>
        <div class="blue">
          <p>Blue</p>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="cyan">
  <p>Cyan</p>
  <div class="blue">
    <p>Blue</p>
    <div>
      <p>Blue</p>
      <div class="orange">
        <p>Orange</p>
        <div>
          <p>Orange</p>
        </div>
      </div>
    </div>
  </div>
</div>


推荐阅读