Zero Block: разбираем параметр Pointer events
▶️ Если вы работаете в Zero Block, например, создаёте кликабельные элементы или настраиваете анимацию, вам не обойтись без параметра Pointer Events. Он делает элементы невидимыми для наведения или клика мышью. За счёт этого можно добавлять самые разные эффекты на сайт.
Давайте разберём работу параметра на конкретном примере. Смотрите карточки 👉
— Добавим кнопку в Zero Block и наложим поверх неё стрелку на прозрачном фоне.
— Нажмём на верхний элемент > перейдём в настройки > Pointer Events и установим значение None.
Теперь верхний элемент стал невидимым для мыши — можно наводить и нажимать на кнопку.
Если для верхнего элемента установить Pointer Events — Auto, на кнопку невозможно будет нажать — её перекрывает верхний элемент.
Закрепим: параметр Pointer events пригодится, если необходимо разместить неактивные элементы поверх того, с чем можно взаимодействовать. Например, можно разместить поверх кнопки листания слайдов в галерее иконку, а поверх кнопки формы заявки — изображение, и они никак не помешают клику.
Поставьте 💛, если хотите узнать, как использовать параметр Pointer Events для создания анимации в Нулевом блоке. Мы расскажем об этом в отдельной публикации.
Практическое применение CSS свойства pointer-events
Что такое pointer-events
CSS свойство pointer-events было опубликовано в CSS4-UI в качестве дополнения к CSS3 свойствам.
W3C.org заявляет в спецификации:
The pointer-events property allows authors to control whether or when an element may be the target of user pointing device (pointer, e.g. mouse) events. This property is used to specify under which circumstance (if any) a pointer event should go “through” an element and target whatever is “underneath” that element instead. This also applies to other “hit testing” behaviors such as dynamic pseudo-classes (:hover, :active, :focus), hyperlinks, and Document.elementFromPoint()
Таким образомpointer-events – это свойство, позволяющее контролировать когда, как и может ли вообще указатель устройства (чаще всего мышь) взаимодействовать с элементом.
pointer-events: none предотвращает события указателя (как правило, мыши) для элемента: hover, active, click и т.п., в том числе и JavaScript событие click.
pointer-events: auto восстанавливает стандартное взаимодействие указателя с элементом.
Есть и другие значения свойства pointer-events, но они используются только при работе с SVG и я их не буду здесь рассматривать.
Небольшая особенность pointer-events, которую обязательно нужно учитывать
Предположим, вы установили для элемента JavaScript отслеживание события click. Затем выставили для него свойство pointer-events: none, а после этого опять поменяли этому элементу значение свойства pointer-events на auto. Тогда JavaScript, вызываемый при событии onclick, будет вызван опять при изменении значения свойства pointer-events на auto.
Кроссбраузерность pointer-events
Pointer-events, на удивление, поддерживается многими версиями браузеров. Но всё же подобные свойства нужно использовать аккуратно, чтобы не лишать пользователей возможности пользоваться основными функциями web приложения в старых версиях браузеров.
Так как же использовать pointer-events без вреда для кроссбраузерности? Можно воспользоваться Modernizr библиотекой для определения поддержки браузера этого свойства. А можно принять во внимание, что по сути подобная проблема возникнет в старой версии IE (так как другие браузеры обычно автоматически обновляются) и воспользоваться условными комментариями, если это возможно (пример 3).
Применение CSS свойства pointer-events на практике
Применений pointer-events в верстке можно найти в принципе столько, насколько у верстальщика хватит фантазии и потребностей. Есть парочка применений, которые и мне кажутся полезными. Напишу о них подробнее.
1. Предотвращение взаимодействия с изображениями
Если, к примеру, вы не хотите, чтобы у пользователя была возможность кликнуть правой кнопкой мыши по размещенному на сайте фото, то вы можете воспользоваться свойством pointer-event. Спасет ли это от незаконного копирования? Вряд ли…но жизнь воришке слегка подпортит.
See the Pen zKDev by Anastasiia Bakai (@positivecrash) on CodePen.
Правой картинке задано как раз свойство pointer-events. Попробуйте на практике покликать.
2. Ускорения скролла
Давненько уже было описано, что скролл – тяжелая процедура, при которой перерисовывается контент. Там же написано, что события для элемента такие, как hover, click и т.п. так же требуют перерисовки элементов, соответственно замедляют работу браузера. На хабре был предложен метод, который позволяет уменьшить подобную нагрузку на браузер как раз с помощью свойства pointer-event! Описывать тут метод не буду, в статье все хорошо описано. Способ, надо сказать, заманчивый. И возможно даже не будет никаких казусов в связи с особенностью обработки JavaScript, описанной мною выше.
3. Дизайн-элементы поверх интерактивных карт
Нарисовала я как-то дизайн, в котором ключевым элементом была карта. Сделала скриншот Google карты и наложила на нее пару теней для украшения:
Она понравилась моему начальнику и всё бы ничего..но вот в Illustrator я наложила на карту тени, а в вёрстке как быть? Тут на помощь как раз придёт CSS свойство pointer-events, который позволит наложить декоративные элементы поверх карты, при этом не “закрывая” области интерактивной карты от взаимодействия с пользователем. Как вы уже догадались, я просто добавлю строчку
pointer-events
Описание
CSS-свойство pointer-events позволяет контролировать события, при которых элемент может стать объектом события мыши. Если это свойство не задано, то к содержимому SVG будут применяться характеристики значения visiblePainted.
Вдобавок к указанию того, что элемент не является объектом события мыши, значение none сообщает событию мыши проходить «через» элемент и обращаться к элементу, находящемуся «под» ним.
| Начальное значение | auto |
|---|---|
| Применяется к | все элементы |
| Наследуется | да |
| Обработка значения | как указано |
| Animation type | discrete |
Синтаксис
Значения
Формальный синтаксис
Примеры
Пример 1
Пример 2
Сделать ссылку на ресурс http://example.com не реагирующей на нажатие(click), наведение(:hover) и т.д.
Примечание
Обратите внимание, что предотвращение того, чтобы элемент был объектом событий мыши, с помощью pointer-events не обязательно означает, что обработчики событий мыши на этом элементе не могут или не будут запускаться. Если у одного из дочерних элементов есть явные pointer-events, позволяющие этому ребёнку быть объектом событий мыши, тогда любые события, нацеленные на этого дочернего элемента, будут проходить через родителя, когда событие перемещается вдоль родительской цепочки и запускает обработчики событий на родительском объекте. Конечно, любая активность мыши в точке на экране, которая покрывается родителем, но не дочерним, не будет поймана ни ребёнком, ни родителем (он пройдёт через «родительский» на «цели» под ним).
Мы хотели бы предоставить более тонкий контроль (а не только auto и none ) в HTML, когда части элемента смогут «поймать» события мыши. Если у вас есть какие-то конкретные вещи, чтобы помочь нам в решении как следует расширить pointer-events для HTML, и которые вы хотели бы сделать с этим свойством, добавьте их в раздел «Использовать случаи» на этой странице вики (не беспокойтесь, мы всё сохраним аккуратно).
Характеристики
Это расширение для элементов HTML, хоть и присутствует в ранних версиях CSS Basic User Module Interface Level 3, было перенесено на level 4.
События указателя
События указателя (Pointer events) – это современный способ обработки ввода с помощью различных указывающих устройств, таких как мышь, перо/стилус, сенсорный экран и так далее.
Краткая история
Сделаем небольшой обзор, чтобы вы поняли общую картину и место событий указателя среди других типов событий.
Давным-давно, в прошлом, существовали только события мыши
Но сенсорные устройства во многих аспектах мощнее, чем мышь. Например, они позволяют касаться экрана сразу в нескольких местах («мульти-тач»). Однако, события мыши не имеют необходимых свойств для обработки таких прикосновений.
Но и этих событий оказалось недостаточно, так как существует много других устройств, таких как перо, у которых есть свои особенности. Кроме того, универсальный код, который отслеживал бы и события касаний и события мыши, неудобно писать.
Для решения этих задач был внедрён стандарт Pointer Events («События Указателя»). Он предоставляет единый набор событий для всех типов указывающих устройств.
К настоящему времени спецификация Pointer Events Level 2 поддерживается всеми основными браузерами, а Pointer Events Level 3 находится в разработке и почти полностью совместима с Pointer Events Level 2.
Если вы не разрабатываете под старые браузеры, такие как Internet Explorer 10, Safari 12, или более ранние версии, больше нет необходимости использовать события мыши или касаний – можно переходить сразу на события указателя.
При этом ваш код будет корректно работать и с сенсорными устройствами и с мышью. Впрочем, у событий указателя есть важные особенности, которые нужно знать, чтобы их правильно использовать, без лишних сюрпризов. Мы отметим их в этой статье.
Типы событий указателя
Схема именований событий указателя похожа на события мыши:
| Событие указателя | Аналогичное событие мыши |
|---|---|
| pointerdown | mousedown |
| pointerup | mouseup |
| pointermove | mousemove |
| pointerover | mouseover |
| pointerout | mouseout |
| pointerenter | mouseenter |
| pointerleave | mouseleave |
| pointercancel | — |
| gotpointercapture | — |
| lostpointercapture | — |
Мы можем заменить события mouse. на аналогичные pointer. в коде и быть уверенными, что с мышью по-прежнему всё будет работать нормально.
Свойства событий указателя
pointerId – уникальный идентификатор указателя, вызвавшего событие.
Идентификатор генерируется браузером. Это свойство позволяет обрабатывать несколько указателей, например сенсорный экран со стилусом и мульти-тач (увидим примеры ниже).
pointerType – тип указывающего устройства. Должен быть строкой с одним из значений: «mouse», «pen» или «touch».
Мы можем использовать это свойство, чтобы определять разное поведение для разных типов указателей.
isPrimary – равно true для основного указателя (первый палец в мульти-тач).
Некоторые устройства измеряют область контакта и степень надавливания, например пальца на сенсорном экране, для этого есть дополнительные свойства:
Эти свойства большинством устройств не поддерживаются, поэтому редко используются. При необходимости, подробности о них можно найти в спецификации.
Мульти-тач
Одной из функций, которую абсолютно не поддерживают события мыши, является мульти-тач: возможность касаться сразу нескольких мест на телефоне или планшете или выполнять специальные жесты.
Вот что происходит, когда пользователь касается сенсорного экрана в одном месте, а затем в другом:
Вот небольшое демо, выводящее события pointerdown и pointerup :
Событие: pointercancel
Событие pointercancel происходит, когда текущее действие с указателем по какой-то причине прерывается, и события указателя больше не генерируются.
К таким причинам можно отнести:
Мы продемонстрируем pointercancel на практическом примере, чтобы увидеть, как это влияет на нас.
Допустим, мы реализуем перетаскивание («drag-and-drop») для нашего мяча, как в начале статьи Drag’n’Drop с событиями мыши.
Вот последовательность действий пользователя и соответствующие события:
Мы бы хотели реализовать перетаскивание самостоятельно, поэтому давайте скажем браузеру не перехватывать его.
Нужно сделать две вещи:
В данном демо произведены нужные действия:
Как вы можете видеть, событие pointercancel больше не срабатывает.
Теперь мы можем добавить код для перемещения мяча и наш drag’n’drop будет работать и для мыши и для устройств с сенсорным экраном.
Захват указателя
Захват указателя – особая возможность событий указателя.
Общая идея очень проста, но поначалу может показаться странной, так как для других событий ничего подобного просто нет.
Эта привязка отменяется:
Захват указателя используется для упрощения операций с переносом (drag’n’drop) элементов.
В качестве примера давайте вспомним реализацию слайдера из статьи Drag’n’Drop с событиями мыши.
Мы делаем элемент для слайдера – полоску с «ползунком» ( thumb ) внутри.
Затем он работает так:
Такое решение выглядит слегка «грязным». Одна из проблем – это то, что движения указателя по документу могут вызвать сторонние эффекты, заставить сработать другие обработчики, не имеющие отношения к слайдеру.
Захват указателя позволяет привязать pointermove к thumb и избежать любых подобных проблем:
Pointer-events
Представим ситуацию, когда у нас один html-элемент расположен поверх другого. Но нам нужно, чтобы нижний элемент был кликабельным или реагировал на hover.
pointer-events : none — элемент перестанет реагировать на hover, click и другие события мыши. Он станет «прозрачным» для взаимодействия, а hover и click будут передаваться элементу, лежащему под ним.
pointer-events : auto — (значение по-умолчанию) включает стандартное поведение элемента.
Изначально свойство «pointer-events» было введено для SVG и должно было стать частью CSS3, но было перенесено в спецификацию CSS4. Кроме «none» и «auto» есть еще несколько значений, но они применимы только к SVG, и мы не будем их рассматривать.
Несмотря на то, что свойство относится к CSS4, pointer-events поддерживается уже большим количеством браузеров и довольно давно. Не работает в IE ниже 11 версии и в Opera Presto. А значит, его можно осторожно использовать для улучшения юзабилити в рамках прогрессивного улучшения.
Проверить, поддерживается ли это свойство браузером, можно с помощью специального теста для Modernizer.
Пример 1
Рассмотрим на практике.
В первом примере для белого градиента, накрывающего текст, pointer-events установлен в none. Текст легко выделяется мышью сквозь градиент. Даже курсор меняет свою форму со стрелки на выделение текста.
Во втором примере pointer-events не задан, маска градиента не даёт выделить текст, курсор имеет форму стрелки, как для нетекстовых элементов.
Пример 2
Задача: сделать так, чтобы ссылка в меню становилась некликабельной, если она ведет на эту же страницу.
Обычно в CMS уже есть какой-либо класс для индикации текущей страницы в меню. Допишем ему pointer-events:






