Обнаружение устройств, поддерживающих hover / Хабр

Приветствую. Представляю вашему вниманию перевод заметки «Detecting Hover-Capable Devices», опубликованной 30 июня 2021 года автором Michelle Barker

К сожалению, поискать на Habr более ранние материалы на аналогичную тему я додумался лишь после публикации. Нашёл качественную статью «Выявление устройств с сенсорными экранами на чистом CSS«. А текущую заметку предлагаю считать дополнительным напоминанием о существовании технологии и повторением пройденного.

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

. some-component {
  /* Styles for touch devices */
}
@media screen and (min-width: 1024px) {
  .some-component {
    /* Styles for hover-able devices */
  }
}

Но на сегодняшний день это не очень-то помогает. В современном IPad разрешение экрана может быть больше, чем у бюджетного ноутбука. Или, например, кто-то может использовать свой планшет как дополнительный монитор — имея в этом случае возможность наводить указатель на элементы. Но в приведённых выше медиазапросах устройства ввода никак не учитываются.

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

Медиазапросы 5 уровня

Помимо уже знакомых медиазапросов, позволяющих определять размер области видимости, спецификация CSS Level 5 Media Queries привнесла новые. Один из них позволяет определить, поддерживает ли основное указывающее устройство пользователя возмжоность наведения (hover). Допустимым является значение hover (будет true для таких устройств, как, например, мышь) и значение none (будет true для планшетов с сенсорными экранами). Использовать данный медиазапрос мы можем следующим образом:

.some-component {
  /* Styles for touch devices */
}
@media (hover: hover) {
  .some-component {
    /* Styles for hover-able devices */
  }
}

Уточнение: На самом деле, функционал hover и pointer является частью спецификации медиазапросов ещё с 4 уровня. Но лишь недавно стали поддерживаться почти всеми браузерами.

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

Pointer

Функционал pointer проверяет наличие и точность указывающего устройства. Допустимыми являются значения coarse (для таких указателей, как палец при использовании устройств с сенсорным экраном), fine (например, для мыши) и none (устройство без указателя).

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

.some-component {
  /* Styles for touch devices, including Android */
}
@media (hover: hover) and (pointer: fine) {
  .some-component {
    /* Styles for hover-able devices */
  }
}

any-hover и any-pointer

Если перечисленного недостаточно, условия any-hover и any-pointer позволяют включать в проверку возможности не только основного, но и любого другого подключённого указывающего устройства. Следовательно, если у вас есть устройство с подключёнными и мышью и сенсорным экраном, запрос any-hover: hover будет true.

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

Пример JavaScript

Недавно я сделал страничку с тремя одинаковыми изображениями, каждое из которых является ссылкой. При наведении курсора на эту ссылку-изображение, подобно всплывающей подсказке, показывается его имя. Но пользователи устройств с сенсорным экраном увидеть подсказку не смогут. Вместо этого, при нажатии сразу будет совершён переход по ссылке, что может раздражать, так как пользователи заранее не знают, куда именно попадут. Именно поэтому я решил при клике не осуществлять переход сразу, а лишь при нажатии на появившуюся дополнительную кнопку. Мы можем использовать тот же медиазапрос для определения устройства с сенсорным экраном в JS, используя

matchMedia:

const list = document.querySelector('[data-list]')
const isHoverableDevice = window.matchMedia(
  '(hover: hover) and (pointer: fine)'
)
/* Hide the block link initially */
blockLink.hidden = true
list.addEventListener('click', (e) => {
  /* Do nothing if target is not a link, or device is hover-capable */
  if (!e.target.dataset.link || isHoverableDevice.matches) return
  /* If touch device, show the block link */
  e.preventDefault()
  blockLink.hidden = false
  blockLink.innerText = `Visit ${e.target.dataset.
link}’s page` blockLink.setAttribute('href', e.target.href) })

Результат:

Доступность

В зависимости от интерфейса, мы можем помочь вспомогательным технологиям, используя атрибуты ARIA, чтобы объявить кнопку, когда произойдут изменения, или переместить на кнопку внимание пользователя. Данный пример с MDN включает демонстрацию того, как использовать ARIA Live Regions для объявления динамических изменений элемента.

Поддержка браузерами

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

Как добавить стили наведения и фокуса с помощью theme.json

В предыдущем уроке вы узнали, как использовать элементы theme.json. В этом уроке я покажу вам примеры того, как добавить стили наведения и фокуса к ссылкам и кнопкам в theme.json.

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

Расчетное время чтения: 3 минуты

Последнее обновление

11 марта 2023 г.0015 :hover , :focus и :active состояния элементов ссылки. Начиная с версии 14.1 вы можете стилизовать для контура и :visited .

ключей , которые вы используете для стилизации этих состояний в theme.json, совпадают с псевдоклассами CSS:

  • styles.elements.link. :наведение
  • стили.элементы.ссылка. :фокус
  • стили.элементы.ссылка. :активный
  • стили.элементы.ссылка. :посетил

и styles.elements.link. схема

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

Примеры

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

Замена подчеркивания широкой ссылки сайта нижней границей:

 {
"версия": 2,
"стили": {
 "элементы":  {
 "ссылка":  {
"типография": {
"textDecoration": "нет"
},
"граница": {
"нижний": {
"ширина": "2px",
"цвет": "текущий цвет",
"стиль": "твердый"
}
},
": hover":
{ "типография": { "textDecoration": "нет" }, "граница": { "нижний": { "ширина": "2px", "цвет": "#111", "стиль": "точечный" } } } } } } }

Добавление границы вокруг основной надписи сайта на :hover:

 {
"версия": 2,
"стили": {
"блоки": {
"ядро/название сайта": {
 "элементы": {   "ссылка": { 
"интервал": {
"заполнение": ".5rem"
},
"типография": {
"textDecoration": "нет"
},
"граница": {
"ширина": "2px",
"цвет": "прозрачный",
"стиль": "твердый"
},
 ": наведение": { 
"типография": {
"textDecoration": "нет"
},
"граница": {
"ширина": "2px",
"цвет": "#111",
"стиль": "твердый"
}
}
}
}
}
}
}
} 

Контур поддерживает ширину, стиль, цвет и смещение. Настройка контура фокуса на всех элементах кнопок:

 {
"версия": 2,
"стили": {
"элементы": {
"кнопка": {
 ": фокус": {
"контур": {
"смещение": "3px",
"ширина": "3px",
"стиль": "твердый",
"цвет синий"
}
} 
}
}
}
}
 

См. урок об изменении вариантов стиля блока, если вы хотите отредактировать вариант стиля контура для блока кнопок.

Стилизация ссылок блока навигации сложнее.
Вы можете выбрать стиль блока навигации или индивидуально оформить внутреннюю навигационную ссылку, список страниц, домашнюю ссылку и блоки подменю.

Этот пример относится к блоку навигации и работает только в том случае, если не используются настройки оформления текста и настройки «Подменю: Открыть по клику».

  • Настройка оформления текста добавляет имя класса, которое повышает специфичность, а стили из theme.json переопределяются.
  • Параметр «Открывать по клику» использует элемент кнопки HTML, а не ссылку .
 {
"версия": 2,
"стили": {
"блоки": {
"ядро/навигация": {
"элементы": {
"связь": {
"типография": {
"textDecoration": "нет"
},
"граница": {
"нижний": {
"ширина": "4px",
"цвет": "прозрачный",
"стиль": "твердый"
}
},
": наведите курсор": {
"типография": {
"textDecoration": "нет"
},
"граница": {
"нижний": {
"ширина": "4px",
"цвет": "текущий цвет",
"стиль": "твердый"
}
}
}
}
}
}
}
}
} 

Создать эффект наведения | Mapbox GL JS

Создание эффекта наведения | Картбокс GL JS | Mapbox

All docschevron-rightMapbox GL JSchevron-rightarrow-leftExampleschevron-rightСоздание эффекта наведения

Используйте события и состояния объектов для создания эффекта наведения для каждого объекта.

Создать эффект наведения