html - 如何编写适用于嵌套 div 并选择最接近匹配项的 CSS 选择器?

标签 html css css-selectors

假设我有一个动态呈现的页面,其中我在一些相互包含的 div 上使用类 class1class2:

<div class="class1">
  ...
  <div class="class2">
    ...
    <div class="insider">

我的 CSS 中也有这些选择器:

.class1 .insider { ... }
.class2 .insider { ... }

现在的问题是,两个选择器都匹配上面的 .insider,而 CSS 源代码后面的选择器将获胜。 如何让 classN 父级最接近 .insider 的选择器获胜。


下面是我重现问题的片段,我还展示了我对内联样式的期望。 .other.another div 在那里显示 .insider 的深度未知,因此直接子选择器 (>) 不在画面中。

/* Layout: irrelevant to the issue */
.outer {
  height: 100px;
  width: 100px;
}
.inner {
  display: inline-block;
  height: 50px;
  width: 50px;
  margin: 25px 25px;
}
.insider {
  text-align: center;
}

/* Colors: the visual part that should be fixed */
.class1 {
  background-color: black;
}
.class2 {
  background-color: lightgray;
}
.class1 .insider {
  color: red;
}
.class2 .insider {
  color: green;
}
<table>
<tr><th>Title</th><th>Actual</th><th>Expected</th><th>Explanation</th></tr>
<tr>
<td>Inside class1-2</td>
<td>
  <div class="outer class1">
    <div class="inner class2">
      <div class="other">
        <p class="insider">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: black;">
    <div class="inner" style="background-color: lightgray;">
      <div class="other">
        <p class="insider" style="color: green;">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2" and not because ".class2 .insider" is declared after ".class1 .insider" in the CSS code. Swap the red and green styles in CSS and the text turns red.</td>
</tr>
<tr>
<td>Inside class2-1</td>
<td>
  <div class="outer class2">
    <div class="inner class1">
      <div class="other">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other">
        <div class="another">
          <p class="insider" style="color: red;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be red because the closest styled parent is "class1".</td>
</tr>
<tr>
<td>Inside class2-1-2</td>
<td>
  <div class="outer class2">
    <div class="inner class1">
      <div class="other class2">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other" style="background-color: lightgray;">
        <div class="another">
          <p class="insider" style="color: green;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2", and not because the outermost styled parent is "class2", nor because of declaration order, see the first case.</td>
</tr>
</table>

所有示例都在 Chrome 开发工具检查器中显示了这一点: enter image description here
可见绿色获胜,因为它具有更大的行号。

最佳答案

.class1 .insider,
.class2 .class1 .insider{
  color: red;
}
.class2 .insider,
.class1 .class2 .insider{
  color: green;
}

此解决方案的缺点是随着 N 的增加,您必须编写的选择器数量也会递归增​​加。但它可以通过像 SASS 或 LESS 这样的预处理库得到帮助。

演示:

/* Layout: irrelevant to the issue */
.outer {
  height: 100px;
  width: 100px;
}
.inner {
  display: inline-block;
  height: 50px;
  width: 50px;
  margin: 25px 25px;
}
.insider {
  text-align: center;
}

/* Colors: the visual part that should be fixed */
.class1 {
  background-color: black;
}
.class2 {
  background-color: lightgray;
}
.class1 .insider,
.class2 .class1 .insider{
  color: red;
}
.class2 .insider,
.class1 .class2 .insider{
  color: green;
}
<table>
<tr><th>Title</th><th>Actual</th><th>Expected</th><th>Explanation</th></tr>
<tr>
<td>Inside class1-2</td>
<td>
  <div class="outer class1">
    <div class="inner class2">
      <div class="other">
        <p class="insider">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: black;">
    <div class="inner" style="background-color: lightgray;">
      <div class="other">
        <p class="insider" style="color: green;">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2" and not because ".class2 .insider" is declared after ".class1 .insider" in the CSS code. Swap the red and green styles in CSS and the text turns red.</td>
</tr>
<tr>
<td>Inside class2-1</td>
<td>
  <div class="outer class2">
    <div class="inner class1">
      <div class="other">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other">
        <div class="another">
          <p class="insider" style="color: red;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be red because the closest styled parent is "class1".</td>
</tr>
<tr>
<td>Inside class2-1-2</td>
<td>
  <div class="outer class2">
    <div class="inner class1">
      <div class="other class2">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other" style="background-color: lightgray;">
        <div class="another">
          <p class="insider" style="color: green;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2", and not because the outermost styled parent is "class2", nor because of declaration order, see the first case.</td>
</tr>
</table>


使用另一个 N 独立版本进行编辑,如果您的嵌套 HTML 布局变得更复杂,您只需要添加选择器:

.unique_class_name1 .insider,
[class~=unique_class_name] .unique_class_name1 .insider{
  color: red;
}
.unique_class_name2 .insider,
[class~=unique_class_name] .unique_class_name2 .insider{
  color: green;
}

虽然在这个版本中,确保模式 unique_class_name 是真正唯一的非常重要,因为 class~=unique_class_name 将命中所有包含 class 属性的元素那把 key 。

/* Layout: irrelevant to the issue */
.outer {
  height: 100px;
  width: 100px;
}
.inner {
  display: inline-block;
  height: 50px;
  width: 50px;
  margin: 25px 25px;
}
.insider {
  text-align: center;
}

/* Colors: the visual part that should be fixed */
.unique_class_name1 {
  background-color: black;
}
.unique_class_name2 {
  background-color: lightgray;
}
.unique_class_name1 .insider,
[class~=unique_class_name] .unique_class_name1 .insider{
  color: red;
}
.unique_class_name2 .insider,
[class~=unique_class_name] .unique_class_name2 .insider{
  color: green;
}
<table>
<tr><th>Title</th><th>Actual</th><th>Expected</th><th>Explanation</th></tr>
<tr>
<td>Inside class1-2</td>
<td>
  <div class="outer unique_class_name1">
    <div class="inner unique_class_name2">
      <div class="other">
        <p class="insider">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: black;">
    <div class="inner" style="background-color: lightgray;">
      <div class="other">
        <p class="insider" style="color: green;">asdf</p>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2" and not because ".class2 .insider" is declared after ".class1 .insider" in the CSS code. Swap the red and green styles in CSS and the text turns red.</td>
</tr>
<tr>
<td>Inside class2-1</td>
<td>
  <div class="outer unique_class_name2">
    <div class="inner unique_class_name1">
      <div class="other">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other">
        <div class="another">
          <p class="insider" style="color: red;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be red because the closest styled parent is "class1".</td>
</tr>
<tr>
<td>Inside class2-1-2</td>
<td>
  <div class="outer unique_class_name2">
    <div class="inner unique_class_name1">
      <div class="other unique_class_name2">
        <div class="another">
          <p class="insider">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>
  <div class="outer" style="background-color: lightgray;">
    <div class="inner" style="background-color: black;">
      <div class="other" style="background-color: lightgray;">
        <div class="another">
          <p class="insider" style="color: green;">asdf</p>
        </div>
      </div>
    </div>
  </div>
</td>
<td>The text color should be green because the closest styled parent is "class2", and not because the outermost styled parent is "class2", nor because of declaration order, see the first case.</td>
</tr>
</table>

关于html - 如何编写适用于嵌套 div 并选择最接近匹配项的 CSS 选择器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35652238/

相关文章:

css - 如何使用 Bootstrap/css 为 2 列网格制作不均匀的行?

javascript - :active vs mousedown event preventDefault()-ed

html - 在出现特定次数后隐藏全部

.net - URL 重写 - 删除 .html 扩展名

javascript - 使用Javascript的YQL财务数据每次都不返回所有查询

html - 如何为 HTML div 标签设置边框

Angular 7,将类添加到组件

CSS 3 nth of type 仅限于类

php - 错误 : 1265 : Data truncated for column exploded string

jquery - 如何阻止导航栏阻止页面