Призрачные кнопки с определением направления наведения в CSS

Призрачные кнопки с определением направления наведения в CSS

От автора: меня бы удивило, если бы вы никогда не сталкивались с призрачными кнопками. Вы знаете их: у них прозрачный фон, который при наведении заливается сплошным цветом. В данной статье мы создадим призрачную кнопку в CSS, но это будет просто. Забавная и хитрая часть — это анимировать заливку этой призрачной кнопки так, чтобы фон заливался цветом в направлении, в котором на нее наводится курсор.

Вот с чего мы начинаем:

В большинстве случаев для заливки сплошным цветом background-color используется transition. Существуют макеты, в которых кнопка может заполняться слева направо, сверху вниз и т. д., для некоторого визуального изящества. Например, вот слева направо:

Тут есть моменты UX, к которым можно придираться. Например, если вы наводите курсор против направления заливки. Рассмотрим этот пример. Кнопка заливается слева, а вы наводите курсор справа.

Призрачные кнопки с определением направления наведения в CSS

Лучше, если кнопка заливается с начальной точки наведения.

Призрачные кнопки с определением направления наведения в CSS

Итак, как мы можем реализовать для кнопки определение направления наведения? Вашей первой мыслью может быть использовать решение на JavaScript, но вместо этого мы можем создать что-то с помощью CSS и небольшой дополнительной разметки.

Вот несколько чистых CSS кнопок-призраков с определением направления!

Давайте рассмотрим это шаг за шагом. Весь код доступен в этой коллекции CodePen.

Создание основы

Давайте начнем с создания основы призрачной кнопки. Разметка проста.

<button>Boo!</button>

Наша CSS реализация будет использовать пользовательские свойства CSS. Это облегчает обслуживание. Они также позволяют легко выполнять настройку.

button { --borderWidth: 5; --boxShadowDepth: 8; --buttonColor: #f00; --fontSize: 3; --horizontalPadding: 16; --verticalPadding: 8; background: transparent; border: calc(var(--borderWidth) * 1px) solid var(--buttonColor); box-shadow: calc(var(--boxShadowDepth) * 1px) calc(var(--boxShadowDepth) * 1px) 0 #888; color: var(--buttonColor); cursor: pointer; font-size: calc(var(--fontSize) * 1rem); font-weight: bold; outline: transparent; padding: calc(var(--verticalPadding) * 1px) calc(var(--horizontalPadding) * 1px); transition: box-shadow 0.15s ease;
} button:hover { box-shadow: calc(var(--boxShadowDepth) / 2 * 1px) calc(var(--boxShadowDepth) / 2 * 1px) 0 #888;
} button:active { box-shadow: 0 0 0 #888;
}

Объединение всего этого дает нам это:

Здорово! У нас есть кнопка и эффект наведения, но мы не можем ее закрасить цветом. Давайте сделаем это.

Добавление заливки

Для этого мы создаем элементы, которые показывают закрашенное состояние призрачной кнопки. Хитрость заключается в том, чтобы обрезать эти элементы через clip-path и скрыть их. Мы можем отобразить их при наведении курсора на кнопку путем перехода clip-path.

Призрачные кнопки с определением направления наведения в CSS

Дочерний элемент с 50% обрезки

Они должны совпадать с родительской кнопкой. Переменные CSS здесь очень помогут.

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

Давайте начнем с добавления базовой заливки слева направо при наведении курсора. Во-первых, давайте добавим span. Этот span должен содержать тот же текстовый контент, что и кнопка.

<button>Boo! <span>Boo!</span>
</button>

Теперь нам нужно выровнять span с кнопкой. Переменные CSS сделают эту тяжелую работу.

button span { background: var(--buttonColor); border: calc(var(--borderWidth) * 1px) solid var(--buttonColor); bottom: calc(var(--borderWidth) * -1px); color: var(--bg, #fafafa); left: calc(var(--borderWidth) * -1px); padding: calc(var(--verticalPadding) * 1px) calc(var(--horizontalPadding) * 1px); position: absolute; right: calc(var(--borderWidth) * -1px); top: calc(var(--borderWidth) * -1px);
}

Наконец, мы обрезаем span вне поля зрения и добавляем правило, которое будет отображать его при наведении, обновляя обрезку. И в завершении мы определяем переход.

button span { --clip: inset(0 100% 0 0); -webkit-clip-path: var(--clip); clip-path: var(--clip); transition: clip-path 0.25s ease, -webkit-clip-path 0.25s ease; // ...Remaining div styles
} button:hover span { --clip: inset(0 0 0 0);
}

Добавление определения направления

Итак, как мы можем добавить определение направления Нам нужны четыре элемента. Каждый элемент будет отвечать за обнаружение точки входа при наведении. С помощью clip-path мы можем разделить область кнопки на четыре сегмента.

Призрачные кнопки с определением направления наведения в CSS

Четыре сегмента :hover

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

<button> Boo! <span></span> <span></span> <span></span> <span></span>
</button>

button span { background: var(--bg); bottom: calc(var(--borderWidth) * -1px); -webkit-clip-path: var(--clip); clip-path: var(--clip); left: calc(var(--borderWidth) * -1px); opacity: 0.5; position: absolute; right: calc(var(--borderWidth) * -1px); top: calc(var(--borderWidth) * -1px); z-index: 1;
}

Мы можем настроить выбор каждого элемента и назначить обрезку и цвет с помощью переменных CSS.

button span:nth-of-type(1) { --bg: #00f; --clip: polygon(0 0, 100% 0, 50% 50%, 50% 50%);
}
button span:nth-of-type(2) { --bg: #f00; --clip: polygon(100% 0, 100% 100%, 50% 50%);
}
button span:nth-of-type(3) { --bg: #008000; --clip: polygon(0 100%, 100% 100%, 50% 50%);
}
button span:nth-of-type(4) { --bg: #800080; --clip: polygon(0 0, 0 100%, 50% 50%);
}

Здорово. Чтобы проверить это, давайте изменим непрозрачность при наведении.

button span:nth-of-type(1):hover,
button span:nth-of-type(2):hover,
button span:nth-of-type(3):hover,
button span:nth-of-type(4):hover { opacity: 1;
}

Призрачные кнопки с определением направления наведения в CSS

Но есть проблема. Если мы наведем курсор через один элемент, а затем переместим его на другой, направление заливки изменится. Это будет отвлекать. Чтобы исправить это, мы можем установить z-index и clip-path при наведении, чтобы сегмент заполнял все пространство.

button span:nth-of-type(1):hover,
button span:nth-of-type(2):hover,
button span:nth-of-type(3):hover,
button span:nth-of-type(4):hover { --clip: polygon(0 0, 100% 0, 100% 100%, 0 100%); opacity: 1; z-index: 2;
}

Собираем все вместе

Мы знаем, как создать анимацию заливки, и мы знаем, как определить направление. Как мы можем объединить их? Используя комбинатор элементов одного уровня!

Это означает, что при наведении курсора на определенный сегмент мы можем обнаружить определенный элемент заливки. Во-первых, давайте обновим разметку.

<button> Boo! <span></span> <span></span> <span></span> <span></span> <b>Boo!</b> <b>Boo!</b> <b>Boo!</b> <b>Boo!</b>
</button>

Теперь мы можем обновить CSS. Ссылаясь на заливку слева направо, мы можем повторно использовать стилизацию. Нам нужно только установить конкретный clip-path для каждого элемента. Я использовал тот же порядок, что имеют значения некоторых свойств. Первый дочерний элемент — верхний, второй — правый и так далее.

button b:nth-of-type(1) { --clip: inset(0 0 100% 0);
}
button b:nth-of-type(2) { --clip: inset(0 0 0 100%);
}
button b:nth-of-type(3) { --clip: inset(100% 0 0 0);
}
button b:nth-of-type(4) { --clip: inset(0 100% 0 0);
}

Последняя часть — обновить соответствующий элемент clip-path при наведении сегмента.

button span:nth-of-type(1):hover ~ b:nth-of-type(1),
button span:nth-of-type(2):hover ~ b:nth-of-type(2),
button span:nth-of-type(3):hover ~ b:nth-of-type(3),
button span:nth-of-type(4):hover ~ b:nth-of-type(4) { --clip: inset(0 0 0 0);
}

Тада! У нас есть чистая кнопка-призрак с определением направления наведения на CSS.

Доступность

В своем текущем состоянии кнопка не соответствует критериям доступности.

Призрачные кнопки с определением направления наведения в CSS

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

<button> Boo! <span></span> <span></span> <span></span> <span></span> <b aria-hidden="true">Boo!</b> <b aria-hidden="true">Boo!</b> <b aria-hidden="true">Boo!</b> <b aria-hidden="true">Boo!</b>
</button>

Больше повторяющегося контента нет.

Вот и все! С помощью дополнительной разметки и некоторых хитростей CSS мы можем создавать призрачные кнопки с определением направления наведения. Используйте препроцессор или соберите компонент в своем приложении, и вам не нужно будет писать весь HTML. Вот демонстрация, использующая встроенные CSS-переменные для управления цветом кнопки.

Автор: Jhey Tompkins

Источник: https://css-tricks.com

Редакция: Команда webformyself.