- Как мы :hover на iOS побеждали…
- Псевдокласс :hover не работает на IOS
- Решение
- Решение
- Наконец-то, решение на чистом CSS для :hover на сенсорных экранах
- «Хм… а в чем проблема?»
- «Уже должно было появиться какое-то решение…»
- Введение Level 4 Media Queries
- «Так что же делать?»
- Можно ли принудительно игнорировать псевдокласс: hover для пользователей iPhone / iPad?
- 16 ответов
Как мы :hover на iOS побеждали…
Ни для кого, думаю, не секрет, что touch-устройства обрабатывают «мышиные» события несколько иначе, не так, как это происходит на десктоп-браузерах…
Самый яркий для меня пример, это обработка псевдокласса :hover . Для начала iOS7, например, не будет реагировать на hover если только на элемент, или его родителя, не навешена обработка события click. Это хорошо видно вот на этом примере: jsfiddle.net/H8EmG — сколько не тыкай пальцем в текст — никаких подчеркиваний не увидишь. А в этом примере jsfiddle.net/H8EmG/1 «тычок» пальцем в текст будет приводить к его подчеркиванию. Интересный факт — пока не ткнем в другой элемент, текст так и будет сидеть под ховером…
Другой интересный пример, это обработка появления элементов «по-наведению»: jsfiddle.net/ASRm9/1 Попробуйте нажать на текст. Сперва вы увидите текст «HOVER!», появившийся внутри строки, а вот второе нажатие уже вызовет alert(‘click’) . Это происходит потому, что iOS понимает что за :hover что-то скрыто, и старается не сломать поведение, заложенное автором сайта.
Но однажды мы столкнулись с такой багой, объяснить которую мы не смогли до сих пор, а на ее локализацию потребовался не один день отладки на iPad… Желающие подробностей, а также хитрого, как мне кажется, способа решения, наверное, всех проблем с :hover разом — прошу под кат…
ВНЕЗАПНО, после очередного обновления сервиса, разработчиком «платформы» которого я являюсь, вскрылась неприятная проблема — на iPad нельзя выбрать ни одну строку практически во всех «таблицах», которые есть на сервисе. «Клик» просто не срабатывает! Надо заметить что «таблица» это не просто строчки и столбцы. В нашем случае это довольно «богатый» UI-элемент c отметками записей, сортировками, группировками, фильтрами, всякими «лесенками» выводом на печать и экспортом в PDF и Excel…
После долгой и нудной локализации проблемы мы выделили изолированный, простой кусок HTML+CSS который давал схожий результат…
- HTML-таблица, несколько строк, несколько столбцов
- В одном из столбцов есть «чекбокс» — div который скрыт по-умолчанию и показывается при наведении на строку. Реализован через :hover
- На строку навешен click
- Таблица имеет размер больше, чем ее контейнер
- Контейнер имеет фиксированный размер и у него включен overflow: scroll
Вот пример: jsfiddle.net/822eG/4. Попробуйте понажимать по строкам таблицы. Hover будет срабатывать (вы увидите «чекбокс») а вот click (и alert ) вы не увидите как не старайтесь наживать на строчки.
На эту тему я даже завел пост на SO stackoverflow.com/questions/21786375/ios-7-hover-click-issue-no-click-triggered-in-some-cases который не принес особого профита, кроме предложения включить (непонятно почему) -webkit-overflow-scrolling: touch на контейнере таблички который реально помогал на примере из jsFiddle, но не помогал на реальном приложении.
В процессе обдумывания этого бардака пришло следующее решение (мой собственный ответ на вопрос на SO) — а что, если :hover заменить на CSS-класс, который «накидывать» кодом, отлавливая mouseenter / mouseleave ? Этот простой фикс на самом деле все решает. Даже работать начинает «веселее» — не надо больше кликать два раза. От первого же нажатия получаем и alert и «чекбокс»: jsfiddle.net/822eG/10
За неимением лучшего варианта стали обдумывать этот… На самом деле у нас очень большой code base. Много как «платформенного» кода, так и «прикладного», на этой платформе основанного. И кто его знает, кто, где и когда, при каких условиях захочет использовать :hover и захочет ли он при это он что-то скрыть или показать. В общем нужно чтобы было «все само (с)» а среднестатистический разработчик не думал о проблемах на iOS.
В итоге получилось следующее решение:
- С помощью MutationObserver (который есть в iOS 6-7) мониторим вставку тэгов link в head документа — мы это можем себе позволить, т.к. все стили у нас заведомо подключаются с помощью require.js и в Safari это гарантированно будет новый link
- При добавлении новых link пробежимся по document.styleSheets и проанализируем их.
- Переберем все правила и найдем среди них те, в селекторе которых присутствует :hover
- Посмотрим на стили для таких селекторов, проверим нет ли там display отличного от none и visibility , отличного от visible
- Если таковые найдутся — перепишем селектор, заменим :hover на .hover (т.е. псевдокласс на обычный класс).
- А на body навесим через delegate обработку mouseenter / mouseleave для найденного селектора, точнее для той его части, которая расположена до :hover
К счастью сделать это оказалось совсем просто… Каждый styleSheet содержит коллекцию rules , в которой лежат собственно правила. Каждое правило обладает свойством selectorText которое можно менять на ходу. А также обладает коллекцией style где во-первых содержится набор свойств, заданных в данном стиле — они хранятся в виде «массива». У style есть .length , перебирая из по длине получим все свойства, измененные в данном стиле. Во-вторых в style содержатся значения измененных свойств. По индексу, равному имени свойства хранится значение свойства.
То есть если у нас, скажем, есть CSS-код:
то у данного правила selectorText == ‘.myClass:hover .block, .myItem:hover .element’ , style.length == 2 , style[0] == ‘color’ , style[1] == ‘display’ , style.color == ‘red’ а style.display == ‘block’ .
Все остальное — дело техники…
К сожалению выяснилось, что первичны обход правил работает (на наших объемах стилей и link-тэгов) не очень быстро… Профилирование показало, что обращение к rules занимает львиную долю времени. Возможно, WebKit инициализирует данное свойство лениво и первое обращение инициирует какой-то глубинный парсинг стилей в набор объектов.
Источник
Псевдокласс :hover не работает на IOS
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Псевдокласс :hover
Надо изменить атрибуты одного div’a при наведение на другой. Написал так: .
Доброго времени суток! Есть два класса(main,subclass), мне нужно что бы при наведении на main.
Не срабатывает псевдокласс :hover !
Обьясните деревянному. Почему не срабатывает код? 9
Решение
Решение
maks_7, сложно сказать не имея перед глазами сути проблемы. Можно попробовать вот таким скриптом: (предварительно подставив Ваши селекторы)
в данном случаи применяется ко всем ссылкам, которые находятся в блоке .menu
Добавлено через 16 минут
если имеется jquery конечно.
Вложения
| menu.rar (3.4 Кб, 7 просмотров) |
maks_7, сразу после вставьте такое:
Блин, плохо нет устройства под рукой ios’овского.
такой вариант:
тамже, после head (вместо всего того, что выше)
и сверху, там где стили css:
HTML CSS псевдокласс hover
Ребят, недавно занялся версткой сайта, опыта до этого не было! столкнулся со следующей задачей: на.
Есть такой элемент странички: При наведении на текст и текст и стрелочка должны менять цвет.
Добрый вечер. Странная вещь твориться, помогите разобраться. Итак, есть картинка с таким стилем.
Источник
Наконец-то, решение на чистом CSS для :hover на сенсорных экранах
Дата публикации: 2019-04-17
От автора: с псевдоклассом :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) <>.
Источник
Можно ли принудительно игнорировать псевдокласс: hover для пользователей iPhone / iPad?
У меня есть несколько меню css на моем сайте, которые расширяются с помощью :hover (без js)
Это работает частично на iDevices, например, касание активирует правило :hover и раскрывает меню, но затем нажатие в другом месте не удаляет :hover . Также, если есть ссылка внутри элемента, который :hover ‘ed, вам нужно дважды нажать, чтобы активировать ссылку (первое нажатие активирует :hover , второе нажатие активирует ссылку).
Мне удалось заставить все работать на iphone, привязав событие touchstart .
Проблема в том, что иногда мобильное сафари по-прежнему выбирает запуск правила :hover из css вместо моих событий touchstart !
Я знаю, что это проблема, потому что, когда я вручную отключаю все правила :hover в CSS, мобильное сафари работает отлично (но обычные браузеры, очевидно, больше не работают).
Есть ли способ динамически «отменить» правила :hover для определенных элементов, когда пользователь находится в мобильном сафари?
Посмотрите и сравните поведение iOS здесь: http://jsfiddle.net/74s35/3/ Примечание: только некоторые свойства css вызывают поведение при двух щелчках, например дисплей: нет; но не фон: красный; или текст-украшение: подчеркивание;
16 ответов
Я обнаружил, что «: hover» непредсказуемо в iPhone / iPad Safari. Иногда нажатие на элемент делает этот элемент «: hover», а иногда он перемещается к другим элементам.
На данный момент у меня просто класс без прикосновений к телу.
И иметь все правила CSS с «: hover» ниже «.no-touch»:
Где-то на странице у меня есть javascript для удаления класса no-touch из тела.
Это не выглядит идеально, но все равно работает.
:hover здесь не проблема. Safari для iOS следует очень странному правилу. Сначала срабатывают mouseover и mousemove ; если что-то изменится во время этих событий, событие click и связанные с ним события не будут запущены:
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 на вашу страницу приведет к тому, что все нажатия на мобильном устройстве будут преобразованы в события щелчка (независимо от того, где пользователь нажимает ), поэтому он также должен решить проблему зависания на мобильных устройствах. В качестве примера я отредактировал вашу скрипку: http://jsfiddle.net/FvACN/8/.
Просто включите библиотеку fastclick.min.js на свою страницу и активируйте ее через:
В качестве дополнительного преимущества это также устранит раздражающую задержку onClick в 300 мс, от которой страдают мобильные устройства.
Использование FastClick имеет несколько незначительных последствий, которые могут иметь или не иметь значения для вашего сайта:
- Если вы нажмете где-нибудь на странице, прокрутите вверх, прокрутите назад вниз, а затем отпустите палец в том же месте, где вы его изначально поместили, FastClick интерпретирует это как «щелчок», хотя, очевидно, это не так. По крайней мере, так это работает в версии FastClick, которую я сейчас использую (1.0.0). Кто-то, возможно, исправил проблему с этой версии.
- FastClick убирает возможность «двойного щелчка».
В основном есть три сценария:
- У пользователя только есть мышь / указатель, и он может активировать :hover
- У пользователя только есть сенсорный экран, и он не может активировать элементы :hover
- У пользователя есть и сенсорный экран, и указатель.
Первоначально принятый ответ отлично работает, если возможны только первые два сценария, когда у пользователя есть указатель или сенсорный экран. Это было обычным явлением, когда ОП задал вопрос 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.
Источник