CSS: последний тип не работает в сочетании с: not
У меня есть что-то, что ведет себя так же, как предоставленный фрагмент. У меня есть список элементов, когда при выборе одного из них я хочу, чтобы он отображался в верхней части списка, что я могу легко сделать с помощью упорядочения по гибкому порядку. За один раз можно выбрать только один. Но поскольку каждый элемент списка имеет границы, последний элемент не должен иметь границы. Простое использование 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>
Ответы
Ответ 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; }
Пересмотренный 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
псевдокласс
Псевдокласс класса :last-of-type
представляет собой элемент, который является последним родственным его типом в списке дочерних элементов его родительского элемента.
<суб > Источник: https://drafts.csswg.org/selectors-3/#last-of-type-pseudo
Подробнее: Как заставить селектор nth-child пропустить скрытые div
Ответ 2
Вместо того, чтобы удалять border-bottom
из последнего невыбранного элемента (что сложно или невозможно в CSS), проще всего установить border-top
для каждого элемента и удалить лишний элемент из объекта визуально над другими, который... .selected
!
Ваше ограничение:
другая граница элементов моего списка, чем на общей внешней границе
разрешено с помощью этого решения.
Обновлено перо
.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>