Содержание статьи
Факундо Коррадини
Если вы когда-нибудь использовали селекторы CSS, вы знаете, что их всего два. The +
комбинатор братьев и сестер выбирает первое соответствие, которое следует сразу после, и ~
комбинатор next-sibling отвечает всем последующим.
Но нет возможности выбрать то, что было раньше. Ни родительские селекторы, ни предыдущие селекторы братьев и сестер просто не являются вещью.
Я знаю, что ты этого хочешь, ты знаешь, что я этого хочу, но строгая правда состоит в том, что их не существует (и, вероятно, никогда не будет). Есть миллион постов о том, почему. Есть даже предложения, как их воплотить. Но мы застряли в однонаправленной обработке правил CSS, скорее всего, чтобы защитить нас от нашего недостатка опыта, из-за чего мы застряем в повторных потоках и даже в бесконечных циклах.
К счастью, как и большинство ограничений CSS, мы можем подделать это.
Первое, что следует рассмотреть, это то, почему мы хотим начать с предыдущих братьев и сестер.
На ум приходят два случая:
- Нам нужно выбрать всех братьев и сестер определенного элемента, и
~
следующий комбинатор братьев и сестер выбирает только те, которые последуют. - Нам нужно выбрать только братьев и сестер, которые были раньше
1. Выбор всех братьев и сестер
Иногда нам нужно выбрать предыдущих и последующих братьев и сестер. Для этого мы можем выбрать родительский элемент и использовать некоторые уловки вокруг него.
К примеру, чтобы выбрать все диапазоны в следующей структуре, когда мы наводим курсор на любой из них, мы можем просто использовать дочерний селектор на родительской наводке. Мы обязательно отключим pointer-events
от родителей и сбросить его на детей. Поэтому любое действие, которое мы хотим осуществить, сработает только тогда, когда мы войдем к ребенку, а не к самому отцу.
Если нужно выбрать всех братьев и сестер кроме при наведении курсора вы можете комбинировать предыдущую технику с :not
селектор, чтобы исключить его.
Типичным вариантом использования для этого является меню:
Приведенный выше код уменьшит непрозрачность всех <
li> eleментs но тот, на который приведен курсор.
Кроме того, вы можете использовать такие фильтры, как селекторы типа и nth, чтобы быть более точным по отношению к братьям и сестрам, на которых вы хотите повлиять.
С некоторыми стилями это должно работать так:
Пожалуйста, запиши: Если вы собираетесь запускать pointer-events:none
Подход, имейте в виду, что он может запутаться со стеканием (может позволить вам выбрать элементы, которые находятся ниже в порядке укладки). Это также не будет работать в IE10 и ниже, кроме того, что вам могут понадобиться события указателя для чего-либо другого. Поэтому будьте особенно аккуратны при его использовании.
2. Выбор того, что было раньше
Для этого варианта использования мы можем изменить порядок в HTML, затем отсортировать его обратно в CSS и использовать ~
следующий комбинатор братьев или сестер или +
селектор соседних братьев и сестер. Таким образом мы выберем следующих братьев и сестер, но будет выглядеть так, словно мы выбираем предыдущих.
Есть несколько способов сделать это. Самый простой и, вероятно, самый старый – это изменение направления записи нашего контейнера:
Если элементы должны отображать фактический текст, вы всегда можете вернуть его обратно:
Но это может выйти из-под контроля многими способами. К счастью, современный набор инструментов CSS делает его гораздо проще и безопаснее. Мы можем просто использовать Flexbox на контейнере и изменить порядок flex-direction:row-reverse
:
Лучше всего в подходе Flexbox состоит в том, что мы не беремся с направлением написания. Нам не нужно сбрасывать детей, и все гораздо более предсказуемо.
Использование «предыдущих братьев и сестер» для создания системы оценки звезд только CSS
Семантически систему рейтинга можно рассматривать как простой список переключателей с соответствующими отметками. Это пригодится, поскольку позволит нам использовать :checked
псевдоселектор для смены братьев и сестер.
Итак, начнем оттуда:
Как мы обсуждали ранее, элементы расположены в обратном порядке, чтобы разрешить использовать селектор предыдущего брата. Обратите внимание, что мы используем символ «белая звезда» Unicode (U+2606) для обозначения пустых звезд.
Давайте отразим их рядом, в правильном (обратном) порядке:
Теперь скройте сами переключатели, никто не хочет этого видеть:
И примените некоторые стили к звездным персонажам:
Единственная действительно важная линия – это position:relative
. Это позволит нам разместить псевдоэлемент с заливкой (U+2605) поверх него, который будет сначала скрыт.
Когда мы наводим курсор на звезду, заполненный псевдоэлемент звезды должен стать видимым для нее и всего Предыдущий братьев и сестер.
То же для выбранного рейтинга, сопоставив все метки, которые есть раньше проверенный переключатель:
Помните что использование флага !important есть с точностью до наоборот хорошей практики. Я делаю это здесь, поскольку без него нет другого способа получить дополнительную функциональность, о которой идет речь в следующей главе.
И последнее, но не менее важное, нам нужно «запомнить» текущий рейтинг на всякий случай, если пользователь захочет его изменить. Например, если они выбрали пять звезд и по какой-либо причине хотят изменить их на четыре, мы должны отображать звезды от 1 до 4 как заполненные, а пятую в качестве полупрозрачной при наведении курсора на четвертую.
Этого можно добиться, изменив непрозрачность Предыдущий брат и сестра проверенного ввода при наведении курсора на контейнер:
Поэтому нам тоже понадобился opacity:1 !important
в начальной декларации при наведении курсора. Иначе это последнее правило выиграло бы конкурс на конкретность и применило бы полупрозрачную заливку ко всему.
И вот мы имеем это, кроссбраузерную, полностью функциональную систему оценивания звезд только CSS с использованием селекторов предыдущих братьев и сестер.
Как видите, то, что это невозможно, не означает, что вы не должны пытаться. Программирование – это выход за пределы. Поэтому всякий раз, когда вы ударитесь о стену, просто нажмите немного сильнее. Или я догадываюсь, что это лучше сравнить?… во всяком случае, вы понимаете, что я имею в виду. Продолжайте хаковать!
Примечание о доступности
Предыдущий фрагмент является упрощением, чтобы его легко понять. это есть нет то, что я бы рекомендовал использовать в производстве из-за многих ограничений доступности.
Чтобы сделать фрагмент более доступным, первым делом будет скрыть переключатель практически любым способом, кроме display:none
чтобы сделать их фокусными. Мы также должны добавить некоторое кольцо фокусировки на весь фрагмент звезд, когда любой элемент внутри фокусируется, с помощью псевдоселектора :focus-within
.
Идентические метки «☆» не имеют смысла для программ считывания с экрана, поэтому лучшим подходом будет иметь a <sp
an> внутри метки с текстом «n звездочек», который будет скрыт от зрячих пользователей.
Также обратный источник HTML+ display:row-reverse
подход делает оценку клавиатуры неудобной, поскольку она не возвращается назад. Доступность Flexbox и клавиатуры – довольно грязная тема, но ближайшее решение для этого – добавление aria-flowto
тег к каждому элементу, по крайней мере, решает проблему для некоторых программ считывания с экрана + комбинаций браузера.
Чтобы получить более доступный фрагмент (используя альтернативную технику смены следующих братьев и сестер, чтобы они выглядели пустыми, а не пытались оценить предыдущие), проверьте фрагменты Патрика Коула, как мы обсуждали в ответах ниже.