Выбор класса и первых 3 остальных; nth-child и nth-of-type бесполезны
У меня есть элемент DOM (#installations) с количеством детей, только один из них имеет класс .selected. Мне нужно выбрать этот класс и первые 3 из остальных (: not (.selected)) и показать их - цель состоит в том, чтобы отображать только 4 элемента, независимо от того, какой элемент имеет класс .selected.
Проблема заключается в выражении:
#installations > *:not(.selected):nth-of-type(-n+3), .selected
: nth-of-type() игнорирует селектор: not() и просто выбирает первые 3 дочерних элемента #installation. Например, если у меня есть этот HTML:
<div id="installations">
<div id="one"/>
<div id="two"/>
<div id="three" class="selected"/>
<div id="four"/>
<div id="five"/>
</div>
У меня будет только один, два, три, а не первые четыре. Логическим следствием является то, что nth-of-type() будет иметь только (один, два, четыре, пять), из которых: not() уже исключил выбранный, выбрав (один, два, четыре) а затем другая часть селектора , .selected
добавит выбранный элемент.
Если выбрано не в первых четырех элементах, скажем, шестое, мы будем выбирать первые три + шестой.
Чтобы уточнить: выбор выделенного плюс 3 смежных элемента также прекрасен. Тем не менее, это тоже сложно в случае, если вы выбрали последние 3 (если мы выберем следующие 3 смежных элемента)
Ответы
Ответ 1
Как упоминалось в моем комментарии, псевдоклассы не обрабатываются последовательно; все они оцениваются вместе над каждым из ваших элементов. Подробнее см. этот ответ.
После небольшого поворота, учитывая ваш HTML и условия, с помощью которых можно выбрать элементы, я придумал следующий длинный список селекторов:
/* The first three children will always be selected at minimum */
#installations > div:nth-child(-n+3),
/* Select .selected if it not among the first three children */
#installations > div.selected,
/* If .selected is among the first three children, select the fourth */
#installations > div.selected:nth-child(-n+3) ~ div:nth-child(4)
Для этого нужно сделать одно простое предположение: класс selected
будет отображаться только по одному элементу за раз.
Вам нужно будет объединить все три селектора в том же правиле, чтобы соответствовать четырем элементам, которые вы ищете. Обратите внимание на запятые в моем коде.
Интерактивная демонстрация jsFiddle (для тестирования селектора с классом в разных дочерних элементах)
Для чего это стоит, проще, если вы можете вернуться к JavaScript. В качестве примера, если вы используете jQuery, его :lt()
селектор делает вещи немного проще:
// Apply styles using this selector instead: #installations > div.with-jquery
$('#installations')
.children('div.selected, div:not(.selected):lt(3)')
.addClass('with-jquery');
Интерактивная демонстрация jsFiddle (проигнорируйте JS-код в этой демонстрации, он только там, чтобы сделать его интерактивным)
Ответ 2
То, что вам нужно использовать, - это смежные селекторные функции. Вот пример, который я приготовил, который работает в Safari (не тестировался в другом месте). Отображаются только элементы "Два", "Три" и "Четыре".
<!DOCTYPE html>
<html>
<head>
<style>
.the-list li {display:none;}
.the-list li.selected {display:block;}
.the-list li.selected + li {display:block;}
.the-list li.selected + li + li {display:block;}
</style>
</head>
<body>
<ol class='the-list'>
<li>One</li>
<li class='selected'>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<li>Six</li>
</ol>
</body>
</html>