[Перевод] Реализация призрачных кнопок с учетом ориентации с помощью CSS

внешний интерфейс CSS
[Перевод] Реализация призрачных кнопок с учетом ориентации с помощью CSS
  • Ghost Buttons: фантомная кнопка — это прозрачная кнопка стандартной формы с тонкой сплошной рамкой. Цвет заливки фона при наведении, чтобы выделить кнопку.
  • direction aware: Осведомленность о направлении. Главное здесь — определить, в каком направлении движется мышь от кнопки.

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

Вот кнопка, готово!

codepen-demo

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

codepen-demo

Если мы поместим мышь с правой стороны кнопки, а отступ начнется с левой стороны, у нас будет плохой опыт!

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

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

Давайте посмотрим на окончательный результат:

codepen-demo

Далее разберем этапы реализации.

Основание

Давайте сначала создадим кнопку, это просто!

<button>Boo!</button>

Мы используем пользовательские свойства 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;
}

codepen-demo

Мы реализовали кнопку и эффект наведения, но без отступов. Давайте двигаться дальше!

добавить отступ

У нас есть дополнительный элемент, так как состояние кнопки заполнено. пройти черезclip-pathскрыть. Установить, когда мышь находится над кнопкойclip-pathПоказать переходы элементов.

Они должны быть выровнены с родительской кнопкой. Здесь наша переменная CSS покажет свои сильные стороны.

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

Давайте начнем с добавления эффекта заполнения слева направо. Главная Мы собираемся добавитьspanЭтикетка, оно имеет тот же контент, что и кнопка.

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

Далее мы будемspanВыровняйте с перекрытием кнопок.

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);
}

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

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

button:hover span {
  --clip: inset(0 0 0 0);
}

codepen-demo

Добавить осведомленность об ориентации

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

Добавляем четыре к кнопке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;
}

Упс, тут проблема. Если мы войдем и наведем указатель мыши на один сегмент, а затем наведем курсор на другой сегмент, направление заливки изменится. Это выглядит очень неправильно. Чтобы исправить это, мы можем установить наведение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;
}

codepen-demo

вместе

Теперь мы знаем, как создать анимацию заливки, и знаем, как определить направление. Так как же их объединить, чтобы добиться желаемого эффекта? Ответ — селекторы братьев и сестер!

Когда мы наводим указатель мыши на направленный блок, мы можем заполнить указанный элемент.

Во-первых, давайте обновим наш код:

<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);
}

На данный момент реализована наша кнопка-призрак, учитывающая направление.

codepen-demo

доступность

Когда кнопка недоступна, будет отображаться следующий статус.

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

<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 мы можем реализовать кнопки-призраки с учетом направления. Используйте препроцессоры или поместите их как компонент в приложение, чтобы нам не приходилось писать их каждый раз.

  1. Вот пример эффекта заполнения текста с помощью ориентации, Метод реализации в основном такой же, как идея этой статьи:Direction aware filling text effect
  2. В этой статье приведены некоторые примеры оценки направления наведения мыши, некоторые из которых реализованы на чистом CSS, а некоторые — на JS.Direction Aware Hover Effects

Переводчик: Марк Вонг

оригинал:CSS-tricks.com/ghost-но для…