仅为元素中的最后两个跨度添加样式

发布于 2025-01-09 10:42:52 字数 1139 浏览 0 评论 0原文

您好,我有这段代码,每个单词都包含在 span 标记中,我只想向最后两个 span 添加样式,即使

标记具有 标签里面并且它有 标签,条件应该是相同的,最后两个 span 在

标签中。

PS 没有 em 标签就可以正常工作

.st span:nth-last-child(-n + 2) {
  background-color: yellow;
}
<p class="st">
  <span>With</span>
  <span>ipsum</span>
  <em>
    <span>dolor</span>
    <span>sit</span>
  </em>
  <span>amet,</span> consectetur adipisicing elit.
</p>

<p class="st">
  <span>Lorem</span>
  <span>ipsum</span>
  <em>
    <span>dolor</span>
    <span>sit</span>
  </em>
  <span>amet,</span>
  <span>consectetur</span>
  <span>adipisicing</span>
  <span>elit.</span>
</p>

应该在没有 em 标签的情况下工作,或者可以用另一个标签代替

Hi I have this code and each word is wrapped into span tag and I want to add styles only to the last two spans, even if <p> tag has <em> tag inside and it has <span> tags the condition should be the same, the last two spans in a <p> tag.

P.S. Without em tag it's working normally

.st span:nth-last-child(-n + 2) {
  background-color: yellow;
}
<p class="st">
  <span>With</span>
  <span>ipsum</span>
  <em>
    <span>dolor</span>
    <span>sit</span>
  </em>
  <span>amet,</span> consectetur adipisicing elit.
</p>

<p class="st">
  <span>Lorem</span>
  <span>ipsum</span>
  <em>
    <span>dolor</span>
    <span>sit</span>
  </em>
  <span>amet,</span>
  <span>consectetur</span>
  <span>adipisicing</span>
  <span>elit.</span>
</p>

Should work without em tag or maybe another tag can be instead

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喜爱纠缠 2025-01-16 10:42:52

立即检查以

这种方式定位 CSS

.st > span:nth-last-child(-n + 2)

https:// codesandbox.io/embed/ged-violet-5w8gyt?fontsize=14&hidenavigation=1&theme=dark

Check Now

target CSS This way

.st > span:nth-last-child(-n + 2)

https://codesandbox.io/embed/aged-violet-5w8gyt?fontsize=14&hidenavigation=1&theme=dark

柳若烟 2025-01-16 10:42:52

您的帖子不清楚元素如何内部直接p.st >应该选择 em 元素 - 我的答案假设您只想选择 元素的最后一个兄弟对当且仅当< /strong> 这对兄弟姐妹也是其父代 p.st 的最后一个子代(不是后代)。


  • 在一般情况下,您所要求的(目前,截至 2022 年 2 月)不可能在 CSS(没有 JavaScript)中实现。

    • 这是因为 CSS 选择器只能基于一组非常有限的元素属性,或者基于元素的祖先以及元素的前一个同级元素来选择元素。
      • 但是选择器不能选择基于未来兄弟或其他祖先的后代的元素。
  • 为了选择“最后 2 个 元素”,您需要一个可以同时选择这两个元素的选择器:

    1. 最后一个子(非后代)元素,但前提是它是一个 ,并且前面还有另一个
    2. 倒数第二个(非后代)元素,但前提是它是一个 元素,并且紧随其后的是另一个
  • 情况 1 很简单:它只是 span + span:last-child:last-of-type { }span + span:nth-last-child(1) { }.

  • 但是,情况 2 是不可能的:CSS 只有 2 个同级选择器(x + yx ~ y),并且这两个选择器都只能用于选择 y 同级,选择 x 同级。

    • 现在可以使用 :has() 伪元素函数,但只能与 querySelector/querySelectorAll 一起使用:它不能在 CSS 规则中使用。
      • 自 2022 年初起,我们正在努力增加支持对于 Chromium 中的 :has() 的受限形式,这是令人兴奋的东西,但不要屏住呼吸 - 我不希望看到它成为主流至少还要再等几年。
        • 一旦受支持(并假设它使用 :scope 关键字),您就可以使用:
          p.st:has( :scope > span + span:last-child:last-of-type ) >跨度 + 跨度:最后一个子级:最后一个类型,
          p.st:has( :scope > span + span:last-child:last-of-type ) >跨度:第 n 个最后一个子级 (2) { }
          

所以这是我们现在能做的最好的事情:

  • 下面的选择器将错误地匹配第一段中的“amet”范围。
  • 我将颜色更改为红色黄色,以便您可以看到哪个规则专门选择哪个元素。
div {
  border: 1px solid black;
  margin: 1em;
}

div > p:first-child {
  font-size: 80%;
  color: #666;
}

p.st > span + span:nth-last-child(1) {
  background-color: red;
}

p.st > span:nth-last-child(2) {
  background-color: yellow;
}
<div>
  <p>Does not match any span elements: even though the last element is a span, that element doesn't have an immediate span sibling:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span> consectetur adipisicing elit.
  </p>
</div>

<div>
  <p>The style rules incorrectly select the "sit" span because they cannot select a <span> followed by a <strong>:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <strong>dolor</strong>
    <span>sit</span>
    <strong>consectetur</strong> adipisicing elit.
  </p>

</div>

<div>
  <p>In this case, the style rule does correctly select the last span sibling pair:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span>
    <span>consectetur</span>
    <span>adipisicing</span>
    <span>elit.</span>
  </p>
</div>


但是,虽然我们无法在一般情况下解决这个问题,但有可能滥用 :not() 和其他选择器函数来阻止选择与其他模式匹配的元素。这种方法只有在您能够控制 HTML 并且知道 HTML 始终具有特定的结构或模式时才可行,在这种情况下我们可以这样做:

div {
  border: 1px solid black;
  margin: 1em;
}

div > p:first-child {
  font-size: 80%;
  color: #666;
}

p.st > span + span:nth-last-child(1) {
  background-color: red;
}

p.st > span:nth-last-child(2):not(strong + span) {
  background-color: yellow;
}
<div>
  <p>Does not match any span elements: even though the last element is a span, that element doesn't have an immediate span sibling:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span> consectetur adipisicing elit.
  </p>
</div>

<div>
  <p>The style rules specifically exclude the case of <code>strong + span</code>, so "sit" is not selected anymore, but this requires every special-case to be excluded, which is only possible if you can make guarantees about the HTML's structure.</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <strong>dolor</strong>
    <span>sit</span>
    <strong>consectetur</strong> adipisicing elit.
  </p>

</div>

<div>
  <p>In this case, the style rule does correctly select the last span sibling pair:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span>
    <span>consectetur</span>
    <span>adipisicing</span>
    <span>elit.</span>
  </p>
</div>

Your post is unclear about how <span> elements inside an immediate p.st > em element should be selected - my answer assumes you only want to select the last sibling pair of <span> elements if and only if the sibling pair is also the last children (not descendants) of their parent p.st.


  • What you're asking is (currently, as of February 2022) impossible to achieve in CSS (without JavaScript) in the general case.

    • This is because CSS selectors can only select elements based on a very restricted set of element properties, or based on an element's ancestors, and an element's previous siblings.
      • But a selector cannot select elements based on future siblings nor descendants of other ancestors.
  • In order to select "the last 2 <span> elements" you need a selector that can select both:

    1. The last child (not descendant) element, but only if it's a <span> that's also preceded by another <span>.
    2. The second-to-last (not descendant) element, but only if it's a <span> element that's also immediately followed by another <span>.
  • Case 1 is straightforward: it's just span + span:last-child:last-of-type { } or span + span:nth-last-child(1) { }.

  • Case 2, however, is impossible: CSS only has 2 sibling selectors (x + y and x ~ y), and both of which can only be used to select the y sibling, not the x sibling.

    • There is the :has() pseudo-element function which you can use today, but only with querySelector/querySelectorAll: it cannot be used in CSS rules.
      • As of early 2022, there is work being done to add support for a restricted form of :has() into Chromium, and it's exciting stuff, but don't hold your breath - I'm not expecting to see it go mainstream for at least another couple of years.
        • Once it is supported (and assuming it uses the :scope keyword) then you could use this:
          p.st:has( :scope > span + span:last-child:last-of-type ) > span + span:last-child:last-of-type,
          p.st:has( :scope > span + span:last-child:last-of-type ) > span:nth-last-child(2) { }
          

So this is the best we can do, right now:

  • The selector below will incorrectly match the "amet" span in the first paragraph.
  • I changed the colors to red and yellow so you can see which rule is selecting which element specifically.

div {
  border: 1px solid black;
  margin: 1em;
}

div > p:first-child {
  font-size: 80%;
  color: #666;
}

p.st > span + span:nth-last-child(1) {
  background-color: red;
}

p.st > span:nth-last-child(2) {
  background-color: yellow;
}
<div>
  <p>Does not match any span elements: even though the last element is a span, that element doesn't have an immediate span sibling:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span> consectetur adipisicing elit.
  </p>
</div>

<div>
  <p>The style rules incorrectly select the "sit" span because they cannot select a <span> followed by a <strong>:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <strong>dolor</strong>
    <span>sit</span>
    <strong>consectetur</strong> adipisicing elit.
  </p>

</div>

<div>
  <p>In this case, the style rule does correctly select the last span sibling pair:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span>
    <span>consectetur</span>
    <span>adipisicing</span>
    <span>elit.</span>
  </p>
</div>


However, while we cannot solve this in the general-case, it is possible to abuse :not() and other selector functions to prevent selecting elements that match other patterns. This approach is only feasible when you have control over the HTML and know that the HTML will always have a particular structure or pattern, in which case we can do this:

div {
  border: 1px solid black;
  margin: 1em;
}

div > p:first-child {
  font-size: 80%;
  color: #666;
}

p.st > span + span:nth-last-child(1) {
  background-color: red;
}

p.st > span:nth-last-child(2):not(strong + span) {
  background-color: yellow;
}
<div>
  <p>Does not match any span elements: even though the last element is a span, that element doesn't have an immediate span sibling:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span> consectetur adipisicing elit.
  </p>
</div>

<div>
  <p>The style rules specifically exclude the case of <code>strong + span</code>, so "sit" is not selected anymore, but this requires every special-case to be excluded, which is only possible if you can make guarantees about the HTML's structure.</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <strong>dolor</strong>
    <span>sit</span>
    <strong>consectetur</strong> adipisicing elit.
  </p>

</div>

<div>
  <p>In this case, the style rule does correctly select the last span sibling pair:</p>
  <p class="st">
    <span>Lorem</span>
    <span>ipsum</span>
    <em>
        <span>dolor</span>
        <span>sit</span>
      </em>
    <span>amet,</span>
    <span>consectetur</span>
    <span>adipisicing</span>
    <span>elit.</span>
  </p>
</div>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文