Управление взаимодействием SVG с помощью свойства Pointer Events
Опубликовано: 2022-03-10pointer-events
.Попробуйте щелкнуть или коснуться изображения SVG ниже. Если вы поместите указатель в нужное место (заштрихованный путь), то домашняя страница Smashing Magazine должна открыться в новой вкладке браузера. Если вы попытаетесь щелкнуть какое-либо пустое место, вы можете быть действительно сбиты с толку.
См. 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
, что означает, что только закрашенные и видимые части будут получать события указателя. Большинство других значений можно разделить на две группы:
- Значения, требующие, чтобы элемент был видимым; а также
- Ценности, которых нет.
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.
Отключите заливку, чтобы ее значение было равно none
. Теперь, если вы попытаетесь навести курсор, щелкнуть или коснуться внутренней части круга, ничего не произойдет. Но если вы сделаете то же самое для области обводки, события указателя все равно будут отправляться. Изменение значения fill
на none
означает, что эта область видна , но не закрашена .
Давайте внесем небольшое изменение в нашу разметку. Мы добавим pointer-events="visible"
к нашему элементу circle
, сохранив при этом fill=none
.
См. Pen Как добавление событий-указателей: все влияет на интерактивность Тиффани Браун (@webinista) на CodePen.
Теперь незакрашенная область, окруженная штрихом, может получать события указателя.
Увеличение кликабельной области изображения SVG
Вернемся к изображению из начала этой статьи. Наш «аметист» — это элемент path
, а не группа полигонов, каждый из которых имеет stroke
и fill
. Это означает, что мы не можем просто добавить pointer-events="all"
и на этом закончить.
Вместо этого нам нужно увеличить область щелчка. Давайте воспользуемся тем, что мы знаем о окрашенных и видимых элементах. В приведенном ниже примере я добавил прямоугольник к нашей разметке изображения.
См. статью Тиффани Браун (@webinista) на CodePen.
Несмотря на то, что этот прямоугольник невидим, он все же технически виден (т.е. visibility: visible
). Однако отсутствие заливки означает, что он не окрашен . Наш образ выглядит так же. На самом деле он работает по-прежнему — щелчок по пустому пространству по-прежнему не запускает операцию навигации. Нам все еще нужно добавить атрибут pointer-events
к нашему элементу a
. Здесь будет работать использование visible
или all
значений.
См. статью Тиффани Браун (@webinista) на CodePen.
Теперь все изображение может получать события указателя.
Использование bounding-box
устранило бы необходимость в фантомном элементе. Все точки внутри ограничивающей рамки будут получать события указателя, включая пустое пространство, заключенное в пути. Но опять же: pointer-events="bounding-box"
широко не поддерживается. Пока это не так, мы можем использовать неокрашенные элементы.
Использование pointer-events
при смешивании SVG и HTML
Еще один случай, когда могут быть полезны pointer-events
: использование SVG внутри HTML-кнопки.
См. 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.
Теперь, когда пользователи нажимают или касаются нашей кнопки, 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
, дополненную примерами.