В прошлом мне часто приходилось выяснять, как добавить стили ко всем элементам внутри контейнера, но не зависший.
Этот эффект требует выбора братьев и сестер зависшего элемента. Я использовал для этого JavaScript, добавляя или удаляя класс, определяющий правильные правила CSS для mouseenter
и mouseleave
события, подобные этому:
Хотя код делает свое дело, моя интуиция всегда подсказывала мне, что для достижения того же результата должен быть какой-то чистый CSS-способ. Несколько лет назад, работая над одним слайдером для своей компании, я придумал решение, похожее на как Крис Гилхоэд воссоздал знаменитую анимацию домашней страницы Netflix и я понял, что JavaScript для этого мне больше не нужен.
Пару месяцев назад я пытался реализовать такой же подход к ленте на основе сетки на веб-сайте моей компании, и — бум — это не сработало из-за промежутка между элементами!
К счастью для меня, оказалось, что так оставаться не должно, и снова мне не понадобился для этого JavaScript.
Разметка и базовый CSS
Давайте начнем кодирование, подготовив правильную разметку:
.grid
основан на сеткесписок;
- и
.grid__child
элементы
дети, с которыми мы хотим взаимодействовать.
Разметка выглядит так:
Стиль должен выглядеть так:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 1rem;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
}
Этот пример кода создаст три элемента списка, занимающих три столбца в сетке.
Сила селекторов CSS
Теперь давайте добавим немного интерактивности. Подход, который я первоначально применил, был основан на двух шагах:
- при наведении курсора на контейнер должны измениться стили всех элементов внутри...
- …кроме того, над которым в данный момент висит курсор.
Давайте начнем с захвата каждого дочернего элемента, пока курсор находится над контейнером:
.grid:hover .grid__child {
/* ... */
}
Во-вторых, давайте исключим зависший в данный момент элемент и уменьшим opacity
любого другого ребенка:
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
И этого было бы вполне достаточно для контейнеров без промежутков между дочерними элементами:
Однако в моем случае я не смог удалить эти пробелы:
Когда я перемещал мышь между плитками, все дочерние элементы исчезали.
Игнорирование пробелов
Мы можем предположить, что промежутки — это части контейнера, которые не перекрываются его дочерними элементами. Мы хотим запускать эффект не каждый раз, когда курсор входит в контейнер, а когда он наводится на один из элементов внутри. Можем ли мы тогда игнорировать курсор, перемещающийся над промежутками?
Да, мы можем, используя pointer-events: none
на .grid
контейнер и вернуть их с pointer-events: auto
на своих дочерних элементах:
.grid {
/* ... */
pointer-events: none;
}
/* ... */
.grid__child {
/* ... */
pointer-events: auto;
}
Давайте просто добавим классный переход по непрозрачности, и у нас есть готовый компонент:
Возможно, будет еще круче, если мы добавим больше тайлов и создадим двухмерный макет:
Окончательный CSS выглядит так:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 3rem;
pointer-events: none;
}
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
pointer-events: auto;
transition: opacity 300ms;
}
Всего двумя дополнительными строками кода мы решили проблему пробелов!
Возможные проблемы
Хотя это компактное решение, в некоторых ситуациях могут потребоваться обходные пути.
К сожалению, этот трюк не сработает, если вы хотите, чтобы контейнер можно было прокручивать, например, как в каком-нибудь горизонтальном слайдере. pointer-events: none
style будет игнорировать не только событие наведения, но и все остальные. В таких случаях можно обернуть .grid
в другом контейнере, например:
Обзор
Я настоятельно рекомендую вам поэкспериментировать и попытаться найти более простой и естественный подход к задачам, от которых обычно ожидается определенный уровень сложности. Веб-технологии, такие как CSS, становятся все более и более мощными, и, используя готовые нативные решения, вы можете добиться отличных результатов без необходимости поддерживать свой код и уступать его поставщикам браузеров.
Я надеюсь, что вам понравился этот краткий урок и вы сочли его полезным. Спасибо!
Автор выбрал Технология Обучение получить пожертвование в рамках Пишите для DOnations программу.