为什么 .class:last-of-type 不能按我的预期工作?

2022-01-10 00:00:00 css-selectors html css

为什么这不起作用?http://jsfiddle.net/84C5W/1/

p{
    display: none;
}
p.visible:last-of-type {
    display: block;
}

<div>
  <p class="visible">This should be hidden</p>
  <p class="visible">This should be displayed</p>
  <p class="">This should be hidden</p>
</div>

事实上,我的 <p> 元素都不可见.如果我在选择器中删除对 .visible 的引用,这确实会显示 div 中的最后一个 <p>,但这不是我想要的.

In fact, none of my <p> elements are visible. If I remove the reference to .visible in my selector, this does show the last <p> in the div, but this is not what I want.

当然,我只能始终保留一个 .visible,但这是用于显示.js 的演示文稿,我无法控制 JavaScript.

Of course I could only keep one .visible at all times, but this is for a reveal.js presentation and I do not have control over the JavaScript.

如何使用 .visible 类选择 div 内的最后一个元素?我不想为此使用 JavaScript.

How can I select the last element inside the div WITH the class .visible? I do NOT want to use JavaScript for this.

推荐答案

您的问题是您正在阅读 :last-of-type 并认为它可以作为 :last-of-class 选择器,而它专门表示仅元素.不幸的是,类的最后一个实例没有选择器.

Your issue is that you're reading :last-of-type and thinking it works as a :last-of-class selector, when instead it specifically means elements only. There is no selector for the last instance of a class, unfortunately.

来自 W3C:

:last-of-type 伪类表示一个元素,它是其类型的最后一个兄弟元素.

The :last-of-type pseudo-class represents an element that is the last sibling of its type.

您将 p.visible:last-of-type 作为选择器,它执行以下操作:

You have p.visible:last-of-type as your selector, which does the following:

  1. 查看 HTML 中每个包含元素中的每个元素列表(例如 1 个或多个元素;没有兄弟姐妹的子元素仍然可以应用 :last-of-type)李>
  2. 查找该列表中的最后一个元素
  3. 检查它是否是 <p> 元素
  4. 检查它是否有类 .visible.

简而言之,您的选择器只会将其样式应用于 <p>.visible 上.在您的标记中,只有前两个 <p> 元素具有该类;第三个没有.

In short, your selector will only apply its styles to a <p> that also has the class .visible on it. In your markup, only the first two <p> elements have that class; the third does not.

这里有一个不同风格的演示来说明:

Here's a demo of different styles to illustrate:

p:last-of-type {
  /* this will be applied in the third paragraph because the pseudo-selector checks for nodes only */
  color: green;
}
p.visible:last-of-type {
  /* this does not get applied, because you are using the pseudo-selector with a specific class in addition to the node type. */
  color: red;
}

<p class="visible">First paragraph.</p>
<p class="visible">Second paragraph.</p>
<p>Third paragraph.</p>

根据你的最终目标,

如何选择带有 .visible 类的 div 中的最后一个元素?我不想为此使用 JavaScript.

How can I select the last element inside the div WITH the class .visible? I do NOT want to use JavaScript for this.

最简单和最高效的方法是反转您尝试应用样式的方式;而不是试图隐藏三个 div 中的两个,其中一个要隐藏的 div 有一个类,另一个要隐藏的 div 没有类,并且要显示的 div 与要隐藏的一个 div 共享相同的类其中 也 有一个类(看到?这很令人困惑),请执行以下操作:

The simplest and most performant way is to invert the way you're trying to apply the styles; instead of trying to hide two out of three divs, where one of the divs to hide has a class and the other div to hide has no class, and the div you want to show shares the same class as the one div you want to hide which also has a class (see? that's pretty confusing), do the following:

  • 仅将类添加到较小的元素(或元素组).
  • 将元素的默认样式设置为您不希望类实现的样式.
  • 将类的样式设置为您想要实现的样式.

p {
    display: none;
}
.visible {
    display: block;
}

<div>
    <p>This should be hidden</p>
    <p class="visible">This should be displayed</p>
    <p>This should be hidden</p>
</div>

正如您从这个演示中看到的那样,您的 HTML 和 CSS 不仅更简单,而且还具有仅使用类选择器而不是 *-of-type 伪选择器的好处,这将使页面加载更快(请参阅下面的更多内容).

As you can see from this demo, not only are your HTML and CSS simpler, but this also has the benefit of using only a class selector rather than a *-of-type pseudo-selector, which will make the page load faster (see more on that below).

为什么没有后跟或父选择器?通过在页面上动态更改一个类名称,这可能会降低许多网页的速度.

Why is there no followed by or parent selector? This could potentially bog down the speed of a lot of webpages by changing just one class name dynamically on the page.

Dave Hyatt,在 2008 年从事 WebKit 实施工作时,提到了一些避免这些实现的原因:

Dave Hyatt, while working on the WebKit implementation in 2008, mentioned some reasons why these implementations are avoided:

使用父选择器很容易意外导致文件范围内的卑躬屈膝.人们可以并且将会滥用这个选择器.支持它就是给人们很多绳子来吊死自己与.

With parent selectors it becomes extremely easy to accidentally cause a document-wide grovel. People can and will misuse this selector. Supporting it is giving people a whole lot of rope to hang themselves with.

关于 CSS3 选择器的可悲事实是,它们真的不应该如果您关心页面性能,请完全使用.装饰你的标记具有类和 ids 并仅在那些上进行匹配,同时避免所有使用兄弟、后代和子选择器实际上会产生一个页面在所有浏览器中的性能都显着提高.

The sad truth about CSS3 selectors is that they really shouldn’t be used at all if you care about page performance. Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers.

相关文章