【问题标题】:CSS :last-of-type not working in combination with :notCSS :last-of-type 不能与 :not 结合使用
【发布时间】:2016-05-29 10:12:22
【问题描述】:

我有一些与提供的 sn-p 行为方式相同的东西。我有一个项目列表,当一个项目被选中时,我希望那个项目显示在列表的顶部,我可以通过弹性排序轻松做到这一点。一次只能选择一个。但是由于每个列表元素都有边框,所以最后一个元素不应该有边框。在大多数情况下,只需使用 li:last-of-type 即可正常工作,除非它是最后一个被选中的列表项。

我已经尝试了几个选择器,它们应该选择没有给定类的无序列表中的最后一个列表项,但 last-of-type 选择器的行为似乎不正常。

如果代码中不清楚,我指的选择器是.selection li:not(.selected):last-of-type。问题是列表底部的双边框。它应该是来自无序列表元素的单个边框。

.selection ul {
  display: flex;
  flex-direction: column;
  border: .15rem solid #666;
}

.selection li {
  order: 2;
  border-bottom: .15rem dashed #666;
}

.selection li.selected {
  order: 1;
}

/** This selector should work in my mind, but it doesn't **/
.selection li:not(.selected):last-of-type {
  border-bottom: none;
}

/** Non-important styles to put it into context **/
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; }
li { padding: 1rem 2rem; background-color: #ebebeb; }
li:hover { background-color: #ccc; }
a { color: inherit; text-decoration: none; }
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">2</a></li>
    <li class="selected">3</li>
  </ul>
</div>

我还创建了这个Codepen snippet 来演示这个问题。

我感觉这是:last-of-type 选择器的问题,也许我用错了,但在我看来,上面的选择器应该可以工作。

任何有关如何解决此问题的帮助或见解,或选择元素的其他方式,或对为什么这不起作用的见解将不胜感激。

【问题讨论】:

  • 听起来就像nth-of-class的问题,当然,不存在。
  • 您还应该知道 nth-of-type 与 DOM 一起使用,但 flexbox order 是纯粹的视觉
  • 嗯,它更像是last-of-not-class
  • Potayto / Potahto :)
  • 我真的很喜欢 /** 将其置于上下文中的非重要样式 **/ .. 我希望所有发布问题的人都可以这样做(而不是与问题无关的一行行代码)

标签: html css css-selectors flexbox


【解决方案1】:

考虑这种替代方法:

  • 完全摆脱 :not 选择器
  • 仅在左侧、右侧和顶部为 ul 设置边框
  • 仅将底部边框应用于li

ul {
    display: flex;
    flex-direction: column;
    border-top: .15rem solid #666;
    border-left: .15rem solid #666;
    border-right: .15rem solid #666;
}

li { border-bottom: .15rem solid #666; }

Revised Codepen


这就是您的选择器不起作用的原因:

.selection li:not(.selected):last-of-type { border-bottom: none; }

在我看来,您是说要匹配最后一个 li 元素,只要它没有类 selected

但这不是last-of-type 的工作方式。如果li 是兄弟,则选择器将匹配它,而不管class选择器匹配 DOM 元素。这意味着即使您将 display: none 应用于 li,选择器仍然会匹配它。

6.6.5.9. :last-of-type pseudo-class

:last-of-type 伪类 表示一个元素,它是列表中其类型的最后一个兄弟元素 其父元素的子元素。

来源: https://drafts.csswg.org/selectors-3/#last-of-type-pseudo

更多详情:How to get nth-child selector to skip hidden divs

【讨论】:

  • 如果我的列表元素上的边框与一般外部边框上的边框不同,那也很好,正如我在修订后的 sn-p 中所展示的那样。这种方法在这种情况下不起作用。
  • 谢谢你的解释,看来我理解选择器错误。我认为:not 选择器会创建一个新的上下文,:last-of-type 选择器将从该上下文开始。现在我很清楚,事实并非如此。
【解决方案2】:

与其尝试从最后一个未选中的项目中删除 border-bottom(这在 CSS 中很难或不可能),不如为每个项目设置一个 border-top 并在视觉上从项目中删除额外的项目更容易,这是....selected!
你的约束:

我的列表元素上的边框与一般外部边框上的边框不同

允许使用此解决方案。

Updated pen

.selection ul {
  display: flex;
  flex-direction: column;
  border: .15rem solid #666;
}

.selection li {
  order: 2;
  border-top: .15rem dashed #666;
  background: lightblue;
}

.selection li.selected {
  order: 1;
  border-top: none;
  background: tomato;
}

/** Non-important styles to put it into context **/
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; }
li { padding: 1rem 2rem; background-color: #ebebeb; }
li:hover { background-color: #ccc; }
a { color: inherit; text-decoration: none; }
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">2</a></li>
    <li class="selected">3</li>
  </ul>
</div>

【讨论】:

  • 这其实很完美。我觉得现在没有想到它很愚蠢^^。谢谢,这确实符合所有要求。
【解决方案3】:

将此视为一种技巧而不是答案。

只是为了表明它可以在某种程度上用 CSS 完成

黄色元素是被选中的元素。

.selection ul {
  display: flex;
  flex-direction: column;
  border: .15rem solid #666;
}

.selection li {
  order: 2;
  border-bottom: .15rem dashed #666;
}

div.selection li.selected {
  order: 1;
  background-color: yellow;
}

.selection li:nth-last-child(2) {
  order: 3;
}

.selection li:not(.selected):nth-last-child(2) {
  border-bottom: none;
}

.selection li.selected:nth-last-child(2) ~ li {
  border-bottom: none;
}


/** Non-important styles to put it into context **/
ul { list-style: none; padding: 0; width: 25%; margin: 2rem auto; }
li { padding: 1rem 2rem; background-color: #ebebeb; }
li:hover { background-color: #ccc; }
a { color: inherit; text-decoration: none; }
.selection {display: inline-block; width: 160px;}
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">3</a></li>
    <li class="selected">2</li>
  </ul>
</div>
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li><a href="">3</a></li>
    <li><a href="">2</a></li>
  </ul>
</div>
<div class="selection">
  <ul>
    <li><a href="">1</a></li>
    <li class="selected"><a href="">3</a></li>
    <li><a href="">2</a></li>
  </ul>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2017-03-04
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多