- PVSM.RU - https://www.pvsm.ru -
Что мы проверили:
Плагин не оборачивает правила? Нет, всё ок. После сборки hover был в медиазапросах.
Не работает hover: hover? Проверили в эмуляции мобильных устройств — работает.
Значит, проблема не в плагине.
Мы начали тестировать разные модели через Browserstack. На большинстве устройств всё нормально, но есть одно но.
Samsung Galaxy игнорирует всё.
Ему всё равно, что мы оборачиваем hover в @media (hover: hover). Он отвечает: «Да-да, я поддерживаю hover», а потом предательски залипает.
Дальнейшая проверка показала, что дело не только в Galaxy. Похожая история случается и на некоторых моделях Vivo.

В процессе поиска ответов мы наткнулись на интересную статью [1] о том, как определять устройства с тачскрином на чистом CSS. Такой способ удобен и для SSR, поэтому мы его изучили. Были варианты и с хуками, но они работают только на клиенте.
Если интересно, вот ссылки, чтобы прогнать ваши устройства:
Возникает логичный вопрос: как браузер определяет, что событие hover поддерживается?
Мы обратились к исходникам Chromium. Там есть файл event.cc [4], где перечислены все события. В нём видно: браузер получает события от ОС.
А в файле platform_event.h [5] можно заметить, что тип события зависит от платформы (Windows, Mac, iOS, Linux).
То есть:
Аппаратная часть устройства сообщает ОС, что за событие произошло.
ОС передаёт его браузеру через драйверы и обработчики.
Браузер преобразует его в знакомые нам события, с которыми мы работаем.
Отсюда и ответ: если устройство сообщает, что hover есть, браузер возвращает true на window.matchMedia(’(hover: hover)’).
На MDN мы нашли медиазапрос pointer [6]. Он определяет, какое устройство ввода используется:
fine — точное устройство (мышь, тачпад, стилус).
coarse — неточное (сенсорный экран).
Проверить это можно так:
window.matchMedia('(pointer: coarse)');
window.matchMedia(’(pointer: fine)’).
Метод возвращает объект с полем matches, где и видно, какое устройство ввода сейчас активно.
На первый взгляд кажется: давайте использовать только pointer: fine и забудем про hover. Но не всё так просто.
У некоторых устройств pointer: fine возвращает true, но hover они не поддерживают.
Стилусы иногда определяются как fine, но тоже не имеют hover.
Поэтому мы должны проверять оба условия:
@media (hover: hover) and (pointer: fine) { ... }

Если обратиться к спеке W3C [7], то там есть важное уточнение. Даже если устройство имеет pointer: coarse, это не значит, что точные клики невозможны. Это говорит о том, что мы можем совершать точные клики при помощи того же стилуса.
Иными словами: медиазапросы дают разработчику лишь подсказку о том, как лучше строить интерфейс, а не жёсткую гарантию.
Мы пришли к следующему варианту: используем медиазапрос (hover: hover) and (pointer: fine), чтобы hover-стили применялись только на устройствах с мышью или тачпадом.
Варианты внедрения
Обернуть стили вручную. Подходит для небольших проектов.
Допилить оригинальный плагин.
Написать свой.
Так как в репозитории оригинального плагина давно висят нерешённые реквесты, мы решили не ждать и сделать свой.
Когда стало ясно, что простого hover: hover недостаточно, мы решили создать свой плагин.
Чтобы сделать использование плагина удобнее и безопаснее, мы сделали версию на TypeScript [8].
Это дало:
Чёткую типизацию входных и выходных данных;
Упрощённое отлавливание ошибок на этапе разработки;
Более структурный и понятный код для будущих изменений.
Теперь у нас есть «боевая» версия плагина, которую можно смело подключать в проект и не переживать за hover на мобильных устройствах.
История с залипающим hover показала: полагаться только на hover: hover не стоит — иногда он «залипает» и слегка раздражает пользователя, хотя интерфейс при этом и не ломается.
С нашим решением hover остаётся только там, где он действительно нужен, а «притворщики» типа тачскринов больше не вмешиваются.
В результате мы получили полезный и интересный опыт в автоматическом оборачивании hover в медиазапросы с более полным условием. Залипающий hover больше не раздражает, а ручное прописывание условий стало не нашей головной болью — так мы (а теперь и вы) можем чуть расслабиться и довериться автоматике.
Автор: Hwaiteu
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/plugin/433257
Ссылки в тексте:
[1] интересную статью: https://habr.com/ru/companies/ruvds/articles/556156/
[2] Подключение Android к Chrome DevTools: https://developer.chrome.com/docs/devtools/remote-debugging?hl=ru
[3] Локальное тестирование через Browserstack: https://www.browserstack.com/docs/live/local-testing/set-up-local-testing
[4] event.cc: http://event.cc
[5] platform_event.h: https://github.com/chromium/chromium/blob/main/ui/events/platform_event.h
[6] pointer: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
[7] спеке W3C: https://www.w3.org/TR/mediaqueries-4/#pointer
[8] TypeScript: https://github.com/Hwaiteu/postcss-media-hover-fix
[9] Источник: https://habr.com/ru/articles/955650/?utm_source=habrahabr&utm_medium=rss&utm_campaign=955650
Нажмите здесь для печати.