【问题标题】:CSS selector for first heading of the highest level?最高级别的第一个标题的CSS选择器?
【发布时间】:2018-07-27 22:48:06
【问题描述】:

如何选择 DOM 中存在的最高 h* 元素中的第一个?

类似

(h1, h2, h3, h4, h5, h6):first-of-ordered-set

即如果 DOM 树按此顺序具有 h2h3h1h2h1,它将选择第一个 h1
如果 DOM 有 h3h3h2h2h4,它将选择第一个 h2
假设h* 元素没有嵌套。

我怀疑 CSS 没有这种能力,对吧?

Somethink 可能可用:https://css-tricks.com/extremely-handy-nth-child-recipes-sass-mixins/

编辑:为什么我想要它:CMS 系统将此“第一个顶部标题”作为文档的标题(帖子、页面、...)。但它留在页面中。然后它显示标题两次——一次作为帖子标题,一次在正文中。 JavaScript 被移除。顶部的h* 级别可能不同。

【问题讨论】:

  • CSS 有循环吗?我正在寻找纯 CSS 解决方案。
  • 纯CSS不行
  • 我有一个想法,但不确定它是否能涵盖所有情况......
  • CSS 中没有办法,但是您要完成什么?
  • @Ibu,我添加了动机

标签: html css css-selectors html-heading


【解决方案1】:

主要问题是我们在 CSS 中没有以前的选择器。例如,我们可以得到第一个h2,但如果稍后我们找到h1,我们就不能有一个选择器来回退。

这是你可以用 CSS 做的最好的事情。您可以隐藏所需元素之后的所有元素(因此您想要的元素是最后一个可见的元素),但您不能对前面的元素执行相同操作。

h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
}


h1:first-of-type ~ * {
  display:none;
}
h2:first-of-type ~ *:not(h1) {
  display:none;
}
h3:first-of-type ~ h4 {
  display:none;
}


.container {
 border:1px solid;
}
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 3*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

然后你可以结合一个小的 JS 代码来只保留需要的元素:

$('h3:first-of-type').prevAll('h4').hide();
$('h2:first-of-type').prevAll('*:not(h1)').hide();
$('h1:first-of-type').prevAll('*').hide();
h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
}


h1:first-of-type ~ * {
  display:none;
}
h2:first-of-type ~ *:not(h1) {
  display:none;
}
h3:first-of-type ~ h4 {
  display:none;
}

.container {
 border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 1*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

我曾经隐藏元素,但你可以用其他样式做同样的事情:

$('h3:first-of-type').prevAll('h4').addClass('initial');
$('h2:first-of-type').prevAll('*:not(h1)').addClass('initial');
$('h1:first-of-type').prevAll('*').addClass('initial');
h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  color:red;
  font-family:cursive;
  font-style:italic;
}


h1:first-of-type ~ *,
h2:first-of-type ~ *:not(h1),
h3:first-of-type ~ h4,
h1.initial,h2.initial,h3.initial,h4.initial{
  color:initial;
  font-family:initial;
  font-style:initial;
}

.container {
 border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <h3>text 3</h3>
  <h1>text 1*</h1>
  <h2>text 2</h2>
  <h1>text 1</h1>
</div>
<div class="container">
  <h3>text 3</h3>
  <h2>text 2*</h2>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h3>text 3</h3>
  <h3>text 2</h3>
  <h2>text 2*</h2>
  <h4>text 1</h4>
</div>
<div class="container">
  <h1>text 1*</h1>
  <h3>text 2</h3>
  <h2>text 2</h2>
  <h4>text 1</h4>
</div>

【讨论】:

  • 对,CSS 只会向前发展,我相信这与性能有关。可能 CSS 只遍历树一次,并进行了优化,例如元素名称、类名称和 id 的索引。我相信这也是围绕has()引起争议的原因。
【解决方案2】:

我发现了一些东西。 CSS 做不到。 还没有。

W3C 正在起草新功能:

.post-content:has(h1, h2, h3, h4, h5, h6)

:not() 一起,这将满足我的需求:

.post-content:has(h1) h1:first-of-kind,
.post-content:not(:has(h1)) h2:first-of-kind,
.post-content:not(:has(h1,h2)) h3:first-of-kind,
...

有一个问题 - :not() 当前为 can only have a single "simple selector"。如果它支持更多,那么即使没有:has也可以实现。

问候未来的读者,我希望它成功了。 现在,我将其保持开放状态,也许有人会用 CSS 3.1 解决。

【讨论】:

  • 重要提示::has() 将在 JavaScript 中可用。请参阅 WICG 的 Discourse 上的 this (minor) discussion,我明确要求我们推动浏览器来实现它。
猜你喜欢
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
  • 1970-01-01
相关资源
最近更新 更多