Управление взаимодействием SVG с помощью свойства Pointer Events

Опубликовано: 2022-03-10
Краткое резюме ↬ Давайте посмотрим, как формировать интерактивность изображений SVG, то есть управлять тем, какие части документа могут получать щелчки, касания или касания, используя свойство pointer-events .

Попробуйте щелкнуть или коснуться изображения SVG ниже. Если вы поместите указатель в нужное место (заштрихованный путь), то домашняя страница Smashing Magazine должна открыться в новой вкладке браузера. Если вы попытаетесь щелкнуть какое-либо пустое место, вы можете быть действительно сбиты с толку.

См. Pen Amethyst Тиффани Браун (@webinista) на CodePen.

См. Pen Amethyst Тиффани Браун (@webinista) на CodePen.

Это дилемма, с которой я столкнулся во время недавнего проекта, который включал ссылки в изображения SVG. Иногда, когда я нажимал на изображение, ссылка работала. В другой раз этого не было. Сбивает с толку, верно?

Я обратился к спецификации SVG, чтобы узнать больше о том, что может происходить и предлагает ли SVG исправление. Ответ: pointer-events .

Еще после прыжка! Продолжить чтение ниже ↓

Не путать с событиями указателя DOM ( Document Object Model ), события pointer-events являются как свойством CSS, так и атрибутом элемента SVG. С его помощью мы можем управлять тем, какие части документа или элемента SVG могут получать события от указывающего устройства, такого как мышь, трекпад или палец.

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

Нестандартно: «Модель формы» SVG

Использование CSS с HTML накладывает модель макета блока на HTML. В модели макета блока каждый элемент создает прямоугольник вокруг своего содержимого. Этот прямоугольник может быть встроенным, встроенным, атомарным встроенным или блочным, но это все равно прямоугольник с четырьмя прямыми углами и четырьмя ребрами. Когда мы добавляем к элементу ссылку или прослушиватель событий, интерактивная область соответствует размерам прямоугольника.

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

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

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

Окрашенные и видимые элементы

Элементы SVG можно «заливать», а можно «штриховать». Заливка относится к внутренней части фигуры. Обводка относится к ее контуру.

Вместе «заливка» и «обводка» представляют собой операции рисования , которые отображают элементы на экране или странице (также известные как холст ). Когда мы говорим о нарисованных элементах , мы имеем в виду, что у элемента есть заливка и/или обводка. Обычно это означает, что элемент также виден.

Однако элемент SVG можно нарисовать так, чтобы он не был виден. Это может произойти, если значение visible атрибута или свойство CSS hidden или если для display установлено значение none . Элемент есть и занимает теоретическое пространство. Мы просто не можем его увидеть (и вспомогательные технологии могут его не обнаружить).

Возможно, еще больше сбивает с толку то, что элемент также может быть видимым — то есть иметь вычисленное значение visibility visible — без закрашивания. Это происходит, когда у элементов отсутствуют как обводка, так и заливка.

Примечание . Значения цвета с альфа-прозрачностью (например rgba(0,0,0,0) ) не влияют на то, окрашен элемент или виден. Другими словами, если элемент имеет альфа-прозрачную заливку или обводку, он закрашивается, даже если его не видно.

Знание того, когда элемент закрашен, виден или не виден, имеет решающее значение для понимания влияния каждого значения pointer-events .

Все или ничего или что-то среднее: ценности

pointer-events является как свойством CSS, так и атрибутом элемента SVG. Его начальное значение — auto , что означает, что только закрашенные и видимые части будут получать события указателя. Большинство других значений можно разделить на две группы:

  1. Значения, требующие, чтобы элемент был видимым; а также
  2. Ценности, которых нет.

painted , fill , stroke и all попадают в последнюю категорию. Их зависимые от видимости аналоги — visiblePainted , visibleFill , visibleStroke и visible — относятся к первому.

Спецификация SVG 2.0 также определяет значение bounding-box . Когда значением pointer-events является bounding-box , прямоугольная область вокруг элемента также может получать события указателя. На момент написания этой статьи только Chrome 65+ поддерживает значение bounding-box .

none также является допустимым значением. Это предотвращает получение элементом и его дочерними элементами каких-либо событий указателя. CSS-свойство pointer-events также можно использовать с элементами HTML. Но при использовании с HTML допустимыми значениями являются только auto и none .

Поскольку значения pointer-events лучше демонстрировать, чем объяснять, давайте посмотрим на некоторые демонстрации.

Здесь у нас есть круг с заливкой и обводкой. Он и нарисован , и виден . Весь круг может получать события указателя, но область вне круга не может.

См. Pen Visible и нарисованный в SVG Тиффани Браун (@webinista) на CodePen.

См. Pen Visible и нарисованный в SVG Тиффани Браун (@webinista) на CodePen.

Отключите заливку, чтобы ее значение было равно none . Теперь, если вы попытаетесь навести курсор, щелкнуть или коснуться внутренней части круга, ничего не произойдет. Но если вы сделаете то же самое для области обводки, события указателя все равно будут отправляться. Изменение значения fill на none означает, что эта область видна , но не закрашена .

Давайте внесем небольшое изменение в нашу разметку. Мы добавим pointer-events="visible" к нашему элементу circle , сохранив при этом fill=none .

См. Pen Как добавление событий-указателей: все влияет на интерактивность Тиффани Браун (@webinista) на CodePen.

См. Pen Как добавление событий-указателей: все влияет на интерактивность Тиффани Браун (@webinista) на CodePen.

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

Увеличение кликабельной области изображения SVG

Вернемся к изображению из начала этой статьи. Наш «аметист» — это элемент path , а не группа полигонов, каждый из которых имеет stroke и fill . Это означает, что мы не можем просто добавить pointer-events="all" и на этом закончить.

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

См. статью Тиффани Браун (@webinista) на CodePen.

См. статью Тиффани Браун (@webinista) на CodePen.

Несмотря на то, что этот прямоугольник невидим, он все же технически виден (т.е. visibility: visible ). Однако отсутствие заливки означает, что он не окрашен . Наш образ выглядит так же. На самом деле он работает по-прежнему — щелчок по пустому пространству по-прежнему не запускает операцию навигации. Нам все еще нужно добавить атрибут pointer-events к нашему элементу a . Здесь будет работать использование visible или all значений.

См. статью Тиффани Браун (@webinista) на CodePen.

См. статью Тиффани Браун (@webinista) на CodePen.

Теперь все изображение может получать события указателя.

Использование bounding-box устранило бы необходимость в фантомном элементе. Все точки внутри ограничивающей рамки будут получать события указателя, включая пустое пространство, заключенное в пути. Но опять же: pointer-events="bounding-box" широко не поддерживается. Пока это не так, мы можем использовать неокрашенные элементы.

Использование pointer-events при смешивании SVG и HTML

Еще один случай, когда могут быть полезны pointer-events : использование SVG внутри HTML-кнопки.

См. Pen Ovxmmy Тиффани Браун (@webinista) на CodePen.

См. Pen Ovxmmy Тиффани Браун (@webinista) на CodePen.

В большинстве браузеров — Firefox и Internet Explorer 11 являются исключениями — значением event.target будет элемент SVG, а не кнопка HTML. Давайте добавим pointer-events="none" к нашему открывающему тегу SVG.

См. Pen How pointer-events: none можно использовать с SVG и HTML Тиффани Браун (@webinista) на CodePen.

См. Pen How pointer-events: none можно использовать с SVG и HTML Тиффани Браун (@webinista) на CodePen.

Теперь, когда пользователи нажимают или касаются нашей кнопки, event.target будет ссылаться на нашу button .

Те, кто хорошо разбирается в DOM и JavaScript, заметят, что использование ключевого слова function вместо стрелочной функции и this вместо event.target решает эту проблему. Однако использование pointer-events="none" (или pointer-events: none; в вашем CSS) означает, что вам не нужно запоминать эту конкретную особенность JavaScript.

Заключение

SVG поддерживает тот же вид интерактивности, к которому мы привыкли в HTML. Мы можем использовать его для создания диаграмм, которые реагируют на клики или касания. Мы можем создавать связанные области, которые не соответствуют блочной модели CSS и HTML. А с добавлением pointer-events мы можем улучшить поведение наших документов SVG в ответ на взаимодействие с пользователем.

Браузерная поддержка pointer-events SVG надежна. Каждый браузер, поддерживающий SVG, поддерживает это свойство для документов и элементов SVG. При использовании с элементами HTML поддержка немного менее надежна. Его нет ни в Internet Explorer 10, ни в его предшественниках, ни в любой версии Opera Mini.

В этой части мы только что pointer-events . Для более глубокого технического рассмотрения прочитайте спецификацию SVG. MDN (Mozilla Developer Network) Web Docs предлагает более удобную для веб-разработчиков документацию по pointer-events , дополненную примерами.