Обнаружение устройств, поддерживающих 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 для объявления динамических изменений элемента.

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

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


ссылка на оригинал статьи https://habr.com/ru/articles/570080/