Ищем поддержку hover на css / Хабр

Доброго времени суток, дорогие хабрахабровцы!

При создании адаптивной версии сайта, часто бывают ситуации, когда надо знать: поддерживает ли браузер пользователя hover, или нет. К примеру, выпадающее при наведении подменю, или же различные анимации, привязанные к событию hover — все это нужно только на ПК. На touch-устройствах поведение элементов должно меняться. Так как же задать определенные стили только для устройств с поддержкой hover на css, не забывая о кроссбраузерности?

В начале сразу хочу сказать о том, что есть js-библиотека Modernizr, которая решает эту задачу. Но… Прикручивать эту библиотеку только для определения поддержки hover, вместо написания одного медиа-запроса в css — не лучший вариант, на мой взгляд.

Но и с медиа-запросами не все так просто. Давайте посмотрим, какие есть варианты!

1. media (hover)

div{color:red;}
@media (hover){
/*Поддерживает hover*/
div{color:green;}
}

Данный медиа-запрос позволит отдельно прописывать стили только для устройств, с поддержкой hover. Но давайте посмотрим на поддержку браузерами: caniuse.com/#feat=css-media-interaction

Как видим, он не поддерживается IE и Firefox. Т.е. наш код будет воспринимать эти браузеры, как без поддержки hover. Такой вариант нам не подходит!

2. media (pointer:coarse)

div{color:green;}
@media (pointer:coarse){
/*touch-устройство*/
div{color:red;}
}

Этот запрос работает в точности наоборот, т.е. только для touch-устройств. Поддержка такая же, как и у media (hover), но т.к. IE и Firefox являются браузерами для ПК — то в них и так не должен срабатывать данный медиа-запрос.

Такое решение вполне подходит для тех случаев, когда нужно прописать стили именно для touch-устройств. Но в основном, стоит задача — прописать стили именно для hover. А это означает, что придется сначала писать стили для всех браузеров, а потом сбрасывать их в медиа-запросе. Это не только увеличивает код, но и довольно неудобно, т.к. надо дублировать каждое свойство, измененное при событии hover на элементе.

3. media (hover) +

Выбирая из двух вышеупомянутых вариантов, первый наиболее привлекательный. Была бы еще браузерная поддержка побольше…

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

Итак, данный код будет работать только в IE:

@media (min-width:0\0) {}

А этот медиа-запрос сработает только для Firefox:

@media (min--moz-device-pixel-ratio:0) {}

Так давайте же объединим все 3 запроса!

div{color:red;}
@media (hover) , (min-width:0\0) , (min--moz-device-pixel-ratio:0){
/*Поддерживает hover*/
div{color:green;}
}

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

Запрос поддерживается во всех основных браузерах, и как бонус, корректно работает на Blackberry и в Opera Mini (чего не было во 2 варианте).

Демо сравнения 3х подходов. Зеленый цвет = поддержка hover:

Обнаружение сенсорного ввода для touchscreen или hover для мыши

Ещё совсем недавно информации о размерах экрана было достаточно для предположения, например, что мобильные устройства будут использовать сенсорный ввод для touchscreen, а пользователи устройств с экраном большего размера, вероятнее всего, используют для управления курсором мышь. Разнообразие устройств с помощью которых можно просматривать веб-сайт не позволяет полагаться только на размеры области просмотра (viewport), как на фактор, определяющий выбор CSS и отдельное поведение страницы для touch-устройств.

Когда-то можно было спокойно обходиться только получением размеров экрана:

.some-component {
  /* Устройства с сенсорным вводом */
}
@media screen and (min-width: 1024px) {
  .some-component {
    /* Вероятно тут будет работать hover */
    /* Наверное, это устройство с мышью */
  }
}

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

А кто-то может подключить свой планшет в качестве дополнительного монитора и таким образом получить возможность использовать наведение курсора (hover) на элементы веб-страницы с помощью мыши.

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

Level 5 Media Queries

Спецификация CSS Level 5 Media Queries, помимо уже знакомых для определения размеров области просмотра, предоставляет набор новых медиа-запросов.

Один из них — hover feature поможет определить, есть ли у пользователя возможности наведения основного указателя на элементы страницы с помощью мыши.

Возможные для применения этого медиа-запроса значения: hover (для устройства с мышью) или none (например, для планшета или смартфона с сенсорным вводом).

Медиа-запрос hover можно использовать следующим образом:

.some-component {
  /* Устройства с сенсорным вводом */
}
@media (hover: hover) {
  .some-component {
    /* Тут будет работать hover */
    /* Это устройство с мышью */
  }
}

Функции hover и pointer на самом деле являются частью спецификации Level 4 Media Queries, но лишь недавно стали поддерживаться большинством браузеров.

See this code hover media query on x.xhtml.ru.

Это всё хорошо работает в большинстве браузеров, но в некоторых версиях Android есть функция, при которой долгое нажатие имитирует наведение (hover) и тогда этот медиа-запрос вернёт true. Чтобы предоставить этим пользователям те же стили, что и для других сенсорных устройств с touchscreen, следует обратиться к другой медиа-функции.

Pointer

Функция pointer проверяет, есть ли на устройстве указатель и точность указательного устройства.

Возможные значения: coarse (грубое для, например, пальца на сенсорном экране), fine (точное, например, мышь) или none (отсутствие, устройство без указателя).

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

.some-component {
  /* Устройства с сенсорным вводом, в т.ч. Android */
}
@media (hover: hover) and (pointer: fine) {
  .some-component {
    /* Тут будет работать hover и pointer===fine */
    /* Это устройство с мышью */
  }
}

See this code Hover and pointer media query on x.xhtml.ru.

any-hover и any-pointer

Предыдущие методы использовали для определения основные устройства ввода. Когда недостаточно определять сенсорный ввод только по основному устройству ввода, можно использовать в медиа-запросах функции any-hover и any-pointer, которые проверяют любой тип ввода.

Таким образом, если используется устройство, которое реагирует как на мышь, так и на сенсорный ввод, any-hover: hover будет возвращать true. Cпецификация включает несколько примеров того, как это (а также более сложные комбинации) можно использовать.

Пример для javascript

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

Этот же медиа-запрос для обнаружения сенсорного ввода можно использовать и в JS с помощью

matchMedia:

const list = document. querySelector('[data-list]')
const isHoverableDevice = window.matchMedia(
  '(hover: hover) and (pointer: fine)'
)
const blockLink = document.querySelector('[data-button-link]')
/* сперва скроем blockLink */
blockLink.hidden = true
list.addEventListener('click', (e) => {
  /* ничего не делаем, если target не ссылка, устройство не умеет hover */
  if (!e.target.dataset.link || isHoverableDevice.matches) return
  /* Если это сенсорный экран, перехватываем клик
  показываем ссылку
  */
  e.preventDefault()
  blockLink.hidden = false
  blockLink.innerText = `Visit ${e.target.dataset.link}’s page`
  blockLink.setAttribute('href', e.target.href)
})

Вот пример:

See this code Touch/hover tooltip on x.xhtml.ru.

Доступность

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

Поддержка в браузерах

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

Detecting Hover-Capable Devices.

Устройства Samsung неправильно обрабатывают CSS-запросы наведения @media

Функциональный запрос hover @media позволяет проверить, поддерживает ли основное устройство ввода устройства наведение интерактивных элементов. Он стал частью веб-платформы с CSS Media Queries Level 4. Запрос hover: hover должен совпадать на устройствах с курсором мыши (например, на сенсорной панели), а hover: none должен соответствовать сенсорным экранам (мобильные устройства). ). К сожалению, устройства Samsung говорят, что их сенсорные экраны являются сенсорными панелями.

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

Медиа-запрос поддерживается во всех ведущих веб-браузерах и операционных системах ( ОС ). За исключением Chromium на устройствах Samsung под управлением Android. Chromium — это базовый движок, используемый интернет-браузером Samsung по умолчанию, Google Chrome, Microsoft Edge, Brave и другими.

Затронуто любое устройство с сенсорным экраном Samsung (и соответствующий драйвер ядра Android); включает все устройства Samsung, выпущенные с 2015 года, и некоторые сторонние устройства Android с сенсорными экранами от Samsung.

Проблема, по-видимому, в том, что сенсорный экран сообщает базовой системе, что это и сенсорный экран, и мышь. Технически затронутые устройства сообщают, что у них есть сенсорный экран и тачпад (как на ноутбуке). Ввод, сделанный на сенсорном экране, обрабатывается (несуществующей) сенсорной панелью как ввод с помощью мыши.

Я не знаю, почему это происходит, но я подозреваю, что это как-то связано либо с Samsung S Pen (стилус), либо с Samsung DeX (док-станция, которая создает ощущение рабочего стола). Эти аксессуары, не совместимые со всеми затронутыми устройствами, действуют как мышь с функцией наведения или могут соединять ее с устройством.

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

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

Компания Samsung или команда Chromium могут решить проблему с помощью исправления в Chromium. Такой обходной путь, вероятно, будет достигнут за счет совместимости с S Pen, DeX или чем-то еще, что в первую очередь мотивировало странную реализацию Samsung.

Нет хороших альтернатив этому медиа-запросу. Лучшее, что вы можете сделать, это предположить, что маленькие экраны — это сенсорные экраны, например. используя @media (максимальная ширина: 500 пикселей), (максимальная высота: 500 пикселей) вместо @media (наведение: нет) . (Замените max на min , чтобы заменить hover: hover . )

Firefox для Android использует тот же метод определения возможностей ввода, что и Chromium. Однако он отбрасывает результаты и вместо этого использует независящий указатель курса. Firefox всегда будет соответствовать @media (наведение: нет) и (указатель: грубый) . Хотя это и не идеально, это означает, что Firefox будет правильно указывать устройство ввода большую часть времени.

CSS :hover Selector

« Предыдущая

Справочник по селекторам CSS

Следующая »


Пример

Выбор и стиль ссылки при наведении на нее указателя мыши:

а: наведите {
цвет фона: желтый;
}

Попробуйте сами »

Дополнительные примеры «Попробуйте сами» ниже.


Определение и использование

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

Совет: Селектор :hover можно использовать для всех элементов, а не только по ссылкам.

Совет: Используйте селектор :link для оформления ссылок на непосещенные страницы, селектор :visited для стиля ссылки на посещаемые страницы и :active селектор для оформления активной ссылки.

Примечание: :hover ДОЛЖЕН идти после :link и :visited (если они присутствуют) в определении CSS, чтобы быть эффективным!

Версия: УС1

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

Числа в таблице указывают первую версию браузера, которая полностью поддерживает селектор.

Селектор
:наведение 4,0 7,0 2,0 ​​ 3.1 9,6

Примечание: В IE должен быть объявлен чтобы селектор :hover работал с другими элементами, кроме элемента .


Синтаксис CSS

:hover {
    объявления css ;
} Демо


Дополнительные примеры

Пример

Выберите и настройте стиль элемента

,

и

при наведении на него курсора:

p:hover, h2:hover, a:hover {
    background-color: yellow;
}

Попробуйте сами »

Пример

Выберите и стилизуйте непосещенные, посещенные, наведенные и активные ссылки:

/* непросмотренная ссылка */
a:link {
    color: green;
}

/* посещенная ссылка */
a: посещено {
    цвет: зеленый;
}

/* курсор мыши ссылка */
a:hover {
    цвет: красный;
}

/* выбранная ссылка */
a:активный {
    цвет: желтый;
}

Попробуйте сами »

Пример

Ссылки на разные стили:

a.

Автор записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *