Как отменить hover css на другом разрешении экрана

Обновлено: 04.07.2024

Это работает частично на iDevices, например, касание активирует правило :hover и раскрывает меню, но затем нажатие в другом месте не удаляет :hover . Также, если есть ссылка внутри элемента, который :hover 'ed, вам нужно дважды нажать, чтобы активировать ссылку (первое нажатие активирует :hover , второе нажатие активирует ссылку).

Мне удалось заставить все работать на iphone, привязав событие touchstart .

Проблема в том, что иногда мобильное сафари по-прежнему выбирает запуск правила :hover из css вместо моих событий touchstart !

Я знаю, что это проблема, потому что, когда я вручную отключаю все правила :hover в CSS, мобильное сафари работает отлично (но обычные браузеры, очевидно, больше не работают).

Есть ли способ динамически «отменить» правила :hover для определенных элементов, когда пользователь находится в мобильном сафари?

Я обнаружил, что ": hover" непредсказуемо в iPhone / iPad Safari. Иногда нажатие на элемент делает этот элемент «: hover», а иногда он перемещается к другим элементам.

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

И иметь все правила CSS с ": hover" ниже ".no-touch":

Где-то на странице у меня есть javascript для удаления класса no-touch из тела.

Это не выглядит идеально, но все равно работает.

:hover здесь не проблема. Safari для iOS следует очень странному правилу. Сначала срабатывают mouseover и mousemove ; если что-то изменится во время этих событий, событие click и связанные с ним события не будут запущены:

Diagram of touch event in iOS

mouseenter и mouseleave включены, хотя в таблице они не указаны.

Если вы измените что-либо в результате этих событий, события щелчка не будут запускаться. Это включает что-то более высокое в дереве DOM. Например, это предотвратит работу вашего веб-сайта с помощью jQuery с помощью одиночных кликов:

Изменить: для пояснения, событие jQuery hover включает mouseenter и mouseleave . Они оба предотвратят click , если содержание будет изменено.

Лучшее решение без какой-либо проверки JS, классов css и области просмотра: вы можете использовать Interaction Media Features (Медиа-запросы, уровень 4)

Библиотека обнаружения функций браузера Modernizer включает проверку событий касания.

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

Если события касания не включены, Modernizr может добавить класс no-touch :

А затем используйте этот класс для ваших стилей наведения:

Вы можете загрузить настраиваемую сборку Modernizr, чтобы включить как можно меньше или столько обнаруженных функций, сколько вам нужно.

Вот пример некоторых классов, которые можно применить:

Некоторые устройства (как говорили другие) имеют как события касания, так и мыши. Microsoft Surface, например, имеет сенсорный экран, трекпад И стилус, который фактически вызывает события наведения при наведении курсора на экран.

Любое решение, отключающее :hover на основании наличия событий касания, также повлияет на пользователей Surface (и многие другие подобные устройства). Многие новые ноутбуки сенсорные и будут реагировать на сенсорные события, поэтому отключение зависания - действительно плохая практика.

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

Некоторые уже предлагали использовать Modernizr, ну, Modernizr позволяет создавать свои собственные тесты. По сути, я здесь «абстрагирую» идею браузера, который поддерживает :hover , в тест Modernizr, который я могу использовать в своем коде без жесткого кодирования if (iOS) .

Тогда css становится примерно таким

Только на iOS этот тест завершится ошибкой и отключит опрокидывание.

Лучшая часть такой абстракции заключается в том, что если я обнаружу, что она ломается на определенном Android или если она исправлена ​​в iOS9, я могу просто изменить тест.

Просто включите библиотеку fastclick.min.js на свою страницу и активируйте ее через:

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


Использование FastClick имеет несколько незначительных последствий, которые могут иметь или не иметь значения для вашего сайта:

  1. Если вы нажмете где-нибудь на странице, прокрутите вверх, прокрутите назад вниз, а затем отпустите палец в том же месте, где вы его изначально поместили, FastClick интерпретирует это как «щелчок», хотя, очевидно, это не так. По крайней мере, так это работает в версии FastClick, которую я сейчас использую (1.0.0). Кто-то, возможно, исправил проблему с этой версии.
  2. FastClick убирает возможность «двойного щелчка».

В основном есть три сценария:

  1. У пользователя только есть мышь / указатель, и он может активировать :hover
  2. У пользователя только есть сенсорный экран, и он не может активировать элементы :hover
  3. У пользователя есть и сенсорный экран, и указатель.

Первоначально принятый ответ отлично работает, если возможны только первые два сценария, когда у пользователя есть указатель или сенсорный экран. Это было обычным явлением, когда ОП задал вопрос 4 года назад. Несколько пользователей отметили, что устройства с Windows 8 и Surface делают третий сценарий более вероятным.

Решение iOS проблемы невозможности зависания на устройствах с сенсорным экраном (как подробно описано в @Zenexer) является разумным, но может привести к неправильному поведению простого кода (как отмечено OP). Отключение наведения только для устройств с сенсорным экраном означает, что вам все равно нужно будет написать альтернативу для сенсорного экрана. Обнаружение того, что у пользователя есть и указатель, и сенсорный экран, еще больше запутывает воду (как объяснил @Simon_Weaver).

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

  • Замена всплывающих меню прямыми действиями (всегда видимые ссылки)
  • Замена всплывающих меню контекстными меню
  • Перемещение большого количества контента при наведении на отдельную страницу

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

Версия JQuery в вашем .css использует .no-touch .my-element: hover для всех ваших правил наведения, включая JQuery и следующий скрипт

Затем в теге body добавьте ontouchstart = "removeHoverState ()"

Как только ontouchstart запускает класс для всех состояний наведения, удаляется

Вместо того, чтобы иметь эффекты наведения только при недоступности касания, я создал систему для обработки событий касания, и это решило для меня проблему. Сначала я определил объект для тестирования событий «касания» (эквивалент «щелчка»).

Затем в моем обработчике событий я делаю что-то вроде следующего:

Спасибо @Morgan Cheng за ответ, однако я немного изменил функцию JS для получения " touchstart " (код взят из @Timothy Perez answer), однако для этого вам понадобится jQuery 1.7+

Учитывая ответ, предоставленный Zenexer, шаблон, не требующий дополнительных тегов HTML, выглядит следующим образом:

Этот метод сначала запускает наведение указателя мыши, а затем щелчок.

Я согласен, что отключение наведения для касания - лучший вариант.

Однако, чтобы избавить себя от необходимости переписывать CSS, просто оберните любые элементы :hover в @supports not (-webkit-overflow-scrolling: touch) <>

Для тех, кто часто использует отключение событий :hover в iOS Safari, самый простой способ - использовать медиа-запрос минимальной ширины для ваших событий :hover , который остается выше ширины экрана устройств, которых вы избегаете. . Пример:

Для тех, кто все еще ищет решение, если ничего из вышеперечисленного не сработало,

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

Я пишу веб-сайт, предназначенный для использования как с настольных компьютеров, так и с планшетов. Когда его посещают с рабочего стола, я хочу, чтобы интерактивные области экрана подсвечивались :hover эффектами (разным цветом фона и т. Д.). На планшете нет мыши, поэтому я не хочу никаких эффектов наведения.

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

Как мне получить эффекты наведения, когда я использую мышь, но подавить их, когда я использую сенсорный экран?

Если кто-то думал об этом, я не хочу использовать сниффинг пользовательского агента. Одно и то же устройство может иметь как сенсорный экран, так и мышь (возможно, сегодня это не так распространено, но в будущем станет еще больше). Устройство меня не интересует, меня интересует, как оно сейчас используется: мышь или тачскрин.

Я уже пытался зацепить touchstart , touchmove и touchend событие , и призывая preventDefault() на всех из них, что делает подавляющий «невидимый курсор мыши» некоторое время; но если я быстро нажимаю вперед и назад между двумя разными элементами, после нескольких нажатий он все равно начнет перемещать «курсор мыши» и зажигать эффекты наведения - это как будто меня preventDefault не всегда уважают. Я не буду утомлять вас подробностями, если в этом нет необходимости - я даже не уверен, что это правильный подход; если у кого есть исправление попроще, я весь уши.

Изменить: это можно воспроизвести с помощью стандартного CSS :hover , но вот краткое воспроизведение для справки.

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

Я также отправил образец здесь , что делает выше , а также перехватывает события мыши JQuery в. Вы можете использовать его, чтобы увидеть, что события касания также срабатывают mouseenter , mousemove и mouseleave .

От автора: с псевдоклассом :hover CSS возникали проблемы с тех пор, как на устройстве с сенсорным экраном был установлен первый веб-браузер. Конечно, появлялись определенные решения, но ни одно из них не было достаточным. С новыми Level 4 Media Queries эта проблема, кажется, решена навсегда.

«Хм… а в чем проблема?»

Допустим, вы просто добавили к элементу веб-страницы стиль :hover, поэтому он получает некоторый стиль, когда на него наводится курсор мыши. Просто.

Наведение на настольном компьютере. Источник: //proper-hovering.glitch.me

Проблема возникает, когда пользователь взаимодействует с этим элементом на сенсорном экране: после того, как выполнено нажатие, эффект наведения для элемента закрепляется. Это также происходит, когда элемент даже не активируется касанием, например, если к нему прикоснулись во время прокрутки.


Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Если перетаскивание начинается на элементе, применяется эффект наведения, потому что технически объект указателя (это ваш палец, как правило) находится над элементом. Это проблема само по себе: на сенсорном устройстве это является нежелательным взаимодействием с пользователем.

Тем не менее, ситуация становится еще хуже: после прекращения перетаскивания эффект наведения остается активным!

Наведение на сенсорном экране (эмуляция). Источник: //proper-hovering.glitch.me

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

Ну, есть некоторые, большинство из которых описаны в этой прекрасной статье. Лучшее из них включает в себя использование JavaScript для определения наличия сенсорных функций экрана, применение на основании этого класса для body, а затем явное указание на этот класс каждый раз, когда к любому элементу применяется эффект :hover.

Это метод изначально связан с рядом проблем:

Разработчик может создать сценарий обнаружения, который хорошо работает сегодня, но что будет через два месяца, когда появится какая-то новая технология? Ноутбуки с сенсорными экранами? Съемные сенсорные экраны? Apple Pencil? Я, скорее всего, не заботился бы об этом во время разработки.


Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

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

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

Введение Level 4 Media Queries

Медиа-запросы великолепны. Они в одиночку создали адаптивный веб-дизайн и являются краеугольным камнем в современной мобильной веб-разработке. В качестве отличной инициативы W3C добавил Функции взаимодействия с медиа в качестве рекомендации для L4 Media Queries, и мы можем их использовать для распознавания устройств с сенсорным экраном.

Включены четыре медиа-запроса: hover, any-hover, pointer и any-pointer. Они предоставляют информацию о возможности наведения и типе пользовательских вводов. Информация может быть только о первичном вводе или о любом доступном вводе. Например, @media(hover: hover) будет true, если основной ввод может быть наведением (например, курсор мыши), а @media(any-pointer: coarse) будет true, если какой-либо ввод имеет ограниченную точность (например, сенсорный ввод). Эти медиа-функции предоставляют достаточно информации для правильной обработки :hover.

Одна из проблем заключается в том, что эти запросы на данный момент являются просто рекомендованными кандидатами, что означает, что они могут измениться или даже быть удалены в любое время. Помните об этом при работе с ними и решите, подходит ли это для вашего проекта. Это определенно на данный момент подходит для нас, и мы возлагаем большие надежды на эти спецификации. Тот факт, что все основные браузеры реализовали эти запросы (кроме, конечно, IE), заставляет нас еще более оптимистично смотреть в будущее.

«Так что же делать?»

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

Вот тестовый сайт, с помощью которого вы можете протестировать свое собственное устройство, чтобы определить, какие из этих медиа-запросов применяются к нему, а также увидеть некоторые из наиболее популярных настроек устройств. Браузеры на Android имеют некоторые несоответствия, но другие устройства, кажется, работают нормально. Проверяя разные устройства, он показывает, что ноутбуки можно выбрать с помощью запроса @media(hover: hover) и (pointer: fine) <>.

CSS

Проблемы с псевдоклассом :hover начались еще с тех пор, как на сенсорных устройствах был установлен первый браузер. Конечно, проблемы пытались решить и решали, но полноценным решением это вряд ли можно было назвать. Однако с новыми медиазапросами (Media Queries) 4 уровня проблема, кажется, решена окончательно.

“Хм … а в чем, собственно говоря, заключается проблема?”

Допустим, вы просто добавили псевдокласс :hover к элементу вашей веб-страницы. Следовательно, когда пользователь наводит курсор мыши на этот элемент, то он активирует некоторые правила CSS и меняет свой внешний вид. Легче легкого!

Однако на сенсорном экране с псевдоклассом :hover возникают проблемы: после того, как нажатие выполнено, эффект наведения закрепляется на элементе. Более того, это происходит, даже тогда, когда элемента не касались напрямую. Например, когда пользователь в процессе прокрутки страницы задевает элемент и его отображение меняется, согласно CSS правилам :hover.

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

Подобное поведение элементов может запутать пользователя и подобная практика будет отрицательно сказываться на вашем продукте. Эту проблему необходимо как-то решить.

“Не может же быть, чтобы эту проблему не пытались как-то решить…”

Да, определенные решения выдвигались. Лучшим из них было использование JavaScript для определения наличия сенсорного экрана и последующее применение класса к body . После чего, добавляя к какому-либо элементу псевдокласс :hover, будет происходить явное обращение к этому классу.

Однако подобное решение имеет несколько недостатков:

  1. Разработчик может создать JS-сценарий обнаружения, который работает сегодня, но что с ним будет через пару месяцев, когда появится какая-то новая технология? Ноутбуки с сенсорными экранами? Съемные сенсорные экраны? Apple Pencil? Никто не хотел бы беспокоиться об этом во время разработки.
  2. Использование основанного на компонентах JS-фреймворка с инкапсулированными стилями неудобно. Так как каждый раз, когда активируется :hover, стили этого элемента должны ссылаться на этот глобальный класс.
  3. Это решение может работать по-разному на разных устройствах. Возможно, что для специальных устройств придется придумывать специальное решение. Однако должен быть стандартизированный способ, работающий на всех устройствах.

Media Queries Level 4

Медиазапросы великолепны. Они в одиночку внедрили адаптивный веб-дизайн и их по праву считают краеугольным камнем современной мобильной веб-разработки. Организация W3C добавила функции взаимодействия с мультимедиа в качестве рекомендации для L4 Media Queries, которые мы можем использовать для распознавания устройств с сенсорным экраном.

Четвертый уровень медиазапросов включает в себя: hover , any-hover , pointer , any-pointer . Они предоставляют информацию о возможности применения hover и типе пользовательского ввода. Например, @media (hover: hover) будет true, если hover элемента активируется курсором мыши. А @media (any-pointer: coarse) будет true, если какой-либо ввод имеет ограниченную точность (например, касание по сенсору). Эти мультимедийные функции предоставляют достаточно информации для правильного взаимодействия с hover .

Одна из проблем заключается в том, что медиазапросы на данный момент являются рекомендательными. Это означает, что они могут измениться или даже быть удалены в любое время. Помните об этом при работе с ними. На данный момент это определенно работает, и мы возлагаем большие надежды на эти спецификации. Тот факт, что все основные браузеры реализовали эти запросы (кроме, конечно, IE), делает наше будущее еще более оптимистичным.

«Так что же делать?»

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

С точки зрения UX, мы ищем решение, которое было бы наиболее приятным для пользователя.

Это означает, что на устройствах с сенсорным экраном не будут использоваться hover-эффекты. Особый случай здесь — это ноутбуки с сенсорными экранами. Однако мы можем предполагать, что на таких ноутбуках большую часть времени используется тачпад или компьютерная мышь. Даже если hover-эффект зависает, пользователь может легко использовать мышь / сенсорную панель, чтобы устранить проблему. К счастью, ноутбуки со съемными сенсорными экранами переходят в режим планшета после отсоединения. А это значит, что медиазапрос все правильно обработает и никаких проблем не возникнет.

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

Читайте также: