CSS:last-of-type与以下组合不兼容:not

时间:2016-02-17 15:41:30

标签: html css css3 css-selectors flexbox

我有一些行为与提供的代码段相同。我有一个项目列表,当选择一个项目时,我希望这个项目显示在列表的顶部,我可以轻松地使用灵活排序。一次只能选择一个。但由于每个列表元素都有边框,因此最后一个元素不应该有边框。简单地使用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>
&#13;
&#13;
&#13;

我还创建了此Codepen snippet来证明问题。

我觉得这是:last-of-type选择器的一个问题,也许我错误地使用它,但在我看来,上面的选择器应该有用。

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

3 个答案:

答案 0 :(得分:5)

考虑这种替代方法:

  • 完全摆脱: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

答案 1 :(得分: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>

答案 2 :(得分:1)

将此视为黑客而不是答案。

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

黄色元素是选中的元素。

&#13;
&#13;
.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;}
&#13;
<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>
&#13;
&#13;
&#13;