Анимированные фоновые полосы, которые переходят при наведении PlatoBlockchain Data Intelligence. Вертикальный поиск. Ай.

Анимированные фоновые полосы, которые меняются при наведении

Как часто вы обращаетесь к CSS background-size имущество? Если вы похожи на меня — и, возможно, на многих других фронтендеров — то обычно, когда вы background-size: cover изображение, чтобы заполнить пространство всего элемента.

Что ж, передо мной стояла интересная задача, требующая более сложных размеров фона: фоновые полосы, которые меняются при наведении. Проверьте это и наведите на него курсор:

Там происходит гораздо больше, чем размер фона, но это был трюк, который мне нужен, чтобы заставить полосы переходить. Я подумал, что покажу вам, как я пришел к этому, не только потому, что я думаю, что это действительно хороший визуальный эффект, но и потому, что это потребовало от меня творчества с градиентами и режимами наложения, которые, я думаю, вам могут понравиться.

Давайте начнем с очень простой настройки, чтобы все было просто. я про сингл

в HTML, оформленном в виде зеленого квадрата:

div {
  width: 500px;
  height: 500px;
  background: palegreen;
}
Анимированные фоновые полосы, которые меняются при наведении

Настройка фоновых полос

Если вы сразу подумали о линейном градиенте CSS, когда увидели эти полосы, то мы уже на одной странице. Мы не можем точно сделать повторяющийся градиент в этом случае, так как мы хотим, чтобы полосы занимали неравномерное пространство и переходили их, но мы можем создать пять полос, соединив пять фонов поверх нашего существующего цвета фона и поместив их вверху. -справа от контейнера:

div {
  width: 500px;
  height: 500px;
  background: 
    linear-gradient(black, black) top right,
    linear-gradient(black, black) top 100px right,
    linear-gradient(black, black) top 200px right,
    linear-gradient(black, black) top 300px right,
    linear-gradient(black, black) top 400px right, 
    palegreen;
}

Я сделал горизонтальные полосы, но мы могли бы сделать и вертикальные с подходом, который мы здесь рассматриваем. И мы можем немного упростить это с помощью пользовательских свойств:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
}

Таким образом, --gt значение - градиент и --n — это константа, которую мы используем, чтобы подтолкнуть полосы вниз, чтобы они были смещены по вертикали. И вы, возможно, заметили, что я установил не настоящий градиент, а сплошные черные полосы в linear-gradient() функция — это сделано намеренно, и мы вскоре поймем, почему я это сделал.

Еще одна вещь, которую мы должны сделать, прежде чем двигаться дальше, — это предотвратить повторение нашего фона; в противном случае они будут располагаться плиткой и заполнять все пространство:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
}

Мы могли бы установить background-repeat в background сокращенно, но я решил разбить его здесь, чтобы было легко читать.

Смещение полос

Технически у нас есть полосы, но довольно сложно сказать, потому что между ними нет промежутка, и они покрывают весь контейнер. Это больше похоже на сплошной черный квадрат.

Здесь мы можем использовать background-size имущество. Мы хотим установить как высоту, так и ширину полос, и свойство поддерживает синтаксис с двумя значениями, который позволяет нам сделать именно это. И мы можем связать эти размеры, разделяя их запятой, так же, как мы делали на background.

Давайте начнем с простого, сначала установив ширину. Использование синтаксиса с одним значением для background-size устанавливает ширину и по умолчанию высоту auto. Я использую здесь совершенно произвольные значения, поэтому установите значения, которые лучше всего подходят для вашего дизайна:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
  background-size: 60%, 90%, 70%, 40%, 10%;
}

Если вы используете те же значения, что и я, вы получите следующее:

Разве это не похоже на то, что мы установили ширину для всех полос, не так ли? Это из-за auto поведение высоты синтаксиса с одним значением. Вторая полоса шире остальных под ней и закрывает их. Мы должны установить высоту, чтобы мы могли видеть нашу работу. Все они должны быть одинаковой высоты, и мы действительно можем повторно использовать наши --n переменная, опять же, чтобы все было просто:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
    background-repeat: no-repeat;
    background-size: 60% var(--n), 90% var(--n), 70% var(--n), 40% var(--n), 10% var(--n); // HIGHLIGHT 15
}

Ах, намного лучше!

Добавление промежутков между полосами

Это совершенно необязательный шаг, если в вашем дизайне не требуются промежутки между полосами, но в моем они были, и это не слишком сложно. Изменяем высоту каждой полоски background-size чуть-чуть, уменьшая значение, чтобы они не заполнили все пространство по вертикали.

Мы можем продолжать использовать нашу --n переменная, но вычесть небольшое количество, скажем 5px, С помощью calc() чтобы получить то, что мы хотим.

background-size: 60% calc(var(--n) - 5px), 90% calc(var(--n) - 5px), 70% calc(var(--n) - 5px), 40% calc(var(--n) - 5px), 10% calc(var(--n) - 5px);

Это много повторений, которые мы можем устранить с помощью другой переменной:

div {
  --h: calc(var(--n) - 5px);
  /* etc. */
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Маскировка и смешивание

Теперь давайте поменяем местами palegreen цвет фона, который мы использовали для визуальных целей до этого момента для белого.

div {
  /* etc. */
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    #fff;
  /* etc. */
}

Такой черно-белый узор идеально подходит для маскировки и смешивания. Для этого мы сначала собираемся обернуть наш

в новом родительском контейнере и ввести второй

под ним:

Здесь мы собираемся сделать небольшой рефакторинг CSS. Теперь, когда у нас есть новый родительский контейнер, мы можем передать фиксированный width и height свойства, которые мы использовали на нашем

вон там:

section {
  width: 500px;
  height: 500px;
} 

Я также собираюсь использовать CSS Grid для размещения двух

элементы друг над другом. Это тот же трюк, который Темани Афиф использует для создания своего супер крутые галереи изображений. Идея состоит в том, что мы размещаем оба блока div над полным контейнером, используя метод grid-area свойство и выровняйте все по центру:

section {
  display: grid;
  align-items: center;
  justify-items: center;
  width: 500px;
  height: 500px;
} 

section > div {
  width: inherit;
  height: inherit;
  grid-area: 1 / 1;
}

Теперь проверьте это. Причина, по которой я использовал сплошной градиент от черного к черному ранее, заключается в том, чтобы настроить нас на маскирование и смешивание двух цветов.

слои. Это не настоящая маскировка в том смысле, что мы вызываем mask свойство, но контраст между слоями определяет, какие цвета видны. Область, покрытая белым, останется белой, а область, покрытая черным, просочится. Документация MDN по режимам наложения имеет хорошее объяснение того, как это работает.

Чтобы это заработало, я применю реальный градиент, который мы хотим видеть на первом

применяя правила стиля из нашего исходного

на новом с помощью :nth-child() псевдоселектор:

div:nth-child(1) { 
  background: linear-gradient(to right, red, orange); 
}

div:nth-child(2)  {
  --gt: linear-gradient(black, black);
  --n: 100px;
  --h: calc(var(--n) - 5px);
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    white;
  background-repeat: no-repeat;
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Если мы остановимся здесь, то фактически не увидим никаких визуальных отличий от того, что было раньше. Это потому, что мы еще не сделали фактического смешивания. Итак, давайте сделаем это сейчас, используя screen режим смешивания:

div:nth-child(2)  {
  /* etc. */
  mix-blend-mode: screen;
}

Я использовал бежевый цвет фона в демонстрации, показанной в начале этой статьи. Этот немного более темный не совсем белый цвет позволяет небольшому цвету просачиваться через остальную часть фона:

Эффект наведения

Последняя часть этой головоломки — эффект наведения, который расширяет полосы до полной ширины. Во-первых, давайте напишем для него наш селектор. Мы хотим, чтобы это произошло, когда родительский контейнер (

в нашем случае) зависает. Когда он наведен, мы изменим размер фона полос, содержащихся во втором

:

/* When 
is hovered, change the second div's styles */ section:hover > div:nth-child(2){ /* styles go here */ }

Мы хотим изменить background-size полос на всю ширину контейнера при сохранении той же высоты:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
}

Это «привязывает» фон к полной ширине. Если мы добавим немного transition к этому, то мы видим, что полосы расширяются при наведении:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
  transition: background-size 1s;
}

Вот эта финальная демонстрация еще раз:

Я добавил туда только текст, чтобы показать, как это может выглядеть, если использовать это в другом контексте. Если вы делаете то же самое, то стоит убедиться, что между цветом текста и цветами, используемыми в градиенте, достаточно контраста, чтобы соответствовать Рекомендации WCAG. И хотя мы кратко коснемся доступности, стоит учитывая предпочтения пользователей для уменьшения движения когда дело доходит до эффекта наведения.

Вот и все!

Довольно аккуратно, правда? Я, конечно, так думаю. Что мне нравится в этом, так это то, что его довольно легко поддерживать и настраивать. Например, мы можем изменить высоту, цвет и направление полос, изменив несколько значений. Вы даже можете изменить некоторые другие параметры — например, цвета и ширину — чтобы сделать его еще более настраиваемым.

Мне действительно интересно, если бы вы подошли к этому по-другому. Если это так, пожалуйста, поделитесь в комментариях! Было бы неплохо посмотреть, сколько вариаций мы сможем собрать.

Отметка времени:

Больше от CSS хитрости