Verwalten der SVG-Interaktion mit der Pointer Events-Eigenschaft
Veröffentlicht: 2022-03-10pointer-events
.Versuchen Sie, auf das SVG-Bild unten zu klicken oder zu tippen. Wenn Sie Ihren Mauszeiger an die richtige Stelle setzen (den schattierten Pfad), sollte die Homepage von Smashing Magazine in einem neuen Browser-Tab geöffnet sein. Wenn Sie versucht haben, auf einen weißen Bereich zu klicken, könnten Sie stattdessen wirklich verwirrt sein.
Dies ist das Dilemma, mit dem ich während eines kürzlichen Projekts konfrontiert war, das Links in SVG-Bilder einschloss. Manchmal, wenn ich auf das Bild klickte, funktionierte der Link. Andere Male tat es das nicht. Verwirrend, oder?
Ich habe mich an die SVG-Spezifikation gewandt, um mehr darüber zu erfahren, was passieren könnte und ob SVG eine Lösung bietet. Die Antwort: pointer-events
.
Nicht zu verwechseln mit DOM (Document Object Model) Zeigerereignissen , Zeigerereignisse sind sowohl eine CSS pointer-events
Eigenschaft als auch ein SVG-Elementattribut. Damit können wir verwalten, welche Teile eines SVG-Dokuments oder -Elements Ereignisse von einem Zeigegerät wie einer Maus, einem Trackpad oder einem Finger empfangen können.
Ein Hinweis zur Terminologie: "Zeigerereignisse" ist auch der Name eines geräteunabhängigen Webplattform-Features für Benutzereingaben. In diesem Artikel – und für die Zwecke der pointer-events
Eigenschaft – umfasst der Ausdruck „pointer events“ jedoch auch Maus- und Berührungsereignisse.
Outside Of The Box: Das „Shape Model“ von SVG
Die Verwendung von CSS mit HTML zwingt HTML ein Box-Layout-Modell auf. Im Box-Layout-Modell erzeugt jedes Element ein Rechteck um seinen Inhalt. Dieses Rechteck kann Inline, Inline-Level, Atomic Inline-Level oder Block sein, aber es ist immer noch ein Rechteck mit vier rechten Winkeln und vier Kanten. Wenn wir einem Element einen Link oder einen Ereignis-Listener hinzufügen, entspricht der interaktive Bereich den Abmessungen des Rechtecks.
Hinweis : Das Hinzufügen eines clip-path
zu einem interaktiven Element ändert seine interaktiven Grenzen. Mit anderen Worten, wenn Sie einem a
clip-path
. In ähnlicher Weise wird das Hinzufügen einer Schrägtransformation Rechtecke in Rauten umwandeln.
SVG hat kein Box-Layout-Modell. Sie sehen, wenn ein SVG-Dokument in einem HTML-Dokument innerhalb eines CSS-Layouts enthalten ist, hält sich das Root-SVG-Element an das Box-Layout-Modell. Seine untergeordneten Elemente nicht. Daher gelten die meisten CSS-Layout-bezogenen Eigenschaften nicht für SVG.
Stattdessen hat SVG etwas, was ich ein „Formmodell“ nenne. Wenn wir einem SVG-Dokument oder -Element einen Link oder einen Ereignis-Listener hinzufügen, ist der interaktive Bereich nicht unbedingt ein Rechteck. SVG-Elemente haben einen Begrenzungsrahmen. Der Begrenzungsrahmen ist definiert als: das am engsten passende Rechteck, das an den Achsen des Benutzerkoordinatensystems dieses Elements ausgerichtet ist, das es und seine Nachkommen vollständig umschließt.
Aber zunächst hängt es davon ab, welche Teile eines SVG-Dokuments interaktiv sind, welche Teile sichtbar und/oder gezeichnet sind.
Gemalte vs. sichtbare Elemente
SVG-Elemente können „gefüllt“, aber auch „gestrichelt“ sein. Füllung bezieht sich auf das Innere einer Form. Schlaganfall bezieht sich auf seinen Umriss.
Zusammen sind „Füllung“ und „Strich“ Malvorgänge , die Elemente auf dem Bildschirm oder der Seite (auch als Leinwand bezeichnet) rendern. Wenn wir von gemalten Elementen sprechen, meinen wir, dass das Element eine Füllung und/oder einen Strich hat. In der Regel bedeutet dies, dass das Element auch sichtbar ist.
Ein SVG-Element kann jedoch gezeichnet werden, ohne dass es sichtbar ist. Dies kann passieren, wenn der visible
Attributwert oder die CSS-Eigenschaft hidden
ist oder wenn display
none
ist. Das Element ist da und nimmt theoretischen Raum ein. Wir können es einfach nicht sehen (und unterstützende Technologien können es möglicherweise nicht erkennen).
Was vielleicht noch verwirrender ist, ein Element kann auch sichtbar sein – das heißt, einen berechneten visibility
von visible
haben – ohne gezeichnet zu werden. Dies passiert, wenn Elementen sowohl eine Kontur als auch eine Füllung fehlen.
Hinweis : Farbwerte mit Alpha-Transparenz (z. B. rgba(0,0,0,0)
) haben keinen Einfluss darauf, ob ein Element gemalt oder sichtbar ist. Mit anderen Worten, wenn ein Element eine alphatransparente Füllung oder Kontur hat, wird es gemalt, auch wenn es nicht sichtbar ist.
Zu wissen, wann ein Element gemalt, sichtbar oder beides ist, ist entscheidend, um die Auswirkung jedes pointer-events
zu verstehen.
Alles oder nichts oder etwas dazwischen: Die Werte
pointer-events
ist sowohl eine CSS-Eigenschaft als auch ein SVG-Elementattribut. Sein Anfangswert ist auto
, was bedeutet, dass nur die gezeichneten und sichtbaren Teile Zeigerereignisse erhalten. Die meisten anderen Werte können in zwei Gruppen unterteilt werden:
- Werte, die erfordern, dass ein Element sichtbar ist; und
- Werte, die das nicht tun.
painted
, fill
, stroke
und all
fallen in die letztere Kategorie. Ihre sichtbarkeitsabhängigen Gegenstücke – visiblePainted
, visibleFill
, visibleStroke
und visible
– fallen in erstere.
Die SVG 2.0-Spezifikation definiert auch einen bounding-box
Wert. Wenn der Wert von pointer-events
bounding-box
ist, kann der rechteckige Bereich um das Element auch Pointer-Events empfangen. Zum jetzigen Zeitpunkt unterstützt nur Chrome 65+ den bounding-box
Wert.
none
ist ebenfalls ein gültiger Wert. Es verhindert, dass das Element und seine untergeordneten Elemente Zeigerereignisse empfangen. Die CSS-Eigenschaft pointer-events
kann auch mit HTML-Elementen verwendet werden. Aber bei Verwendung mit HTML sind nur auto
und none
gültige Werte.
Da die Werte von pointer-events
besser demonstriert als erklärt werden, schauen wir uns einige Demos an.
Hier haben wir einen Kreis mit einer Füllung und einem Strich angewendet. Es ist sowohl gemalt als auch sichtbar . Der gesamte Kreis kann Zeigerereignisse empfangen, der Bereich außerhalb des Kreises jedoch nicht.
Deaktivieren Sie die Füllung, sodass ihr Wert none
ist. Wenn Sie jetzt versuchen, den Mauszeiger zu bewegen, zu klicken oder auf das Innere des Kreises zu tippen, passiert nichts. Aber wenn Sie dasselbe für den Strichbereich tun, werden weiterhin Zeigerereignisse abgesetzt. Wenn Sie den fill
auf „ none
“ ändern, wird dieser Bereich sichtbar , aber nicht gezeichnet .
Nehmen wir eine kleine Änderung an unserem Markup vor. Wir fügen unserem circle
pointer-events="visible"
hinzu, während wir fill=none
.
Jetzt kann der unbemalte Bereich, der von dem Strich umgeben ist, Zeigerereignisse empfangen.
Erweitern des anklickbaren Bereichs eines SVG-Bildes
Kehren wir zum Bild vom Anfang dieses Artikels zurück. Unser „Amethyst“ ist ein path
, im Gegensatz zu einer Gruppe von Polygonen mit jeweils einem stroke
und einer fill
. Das heißt, wir können nicht einfach pointer-events="all"
hinzufügen und Schluss machen.
Stattdessen müssen wir den Klickbereich erweitern. Nutzen wir unser Wissen über gemalte und sichtbare Elemente. Im folgenden Beispiel habe ich unserem Bild-Markup ein Rechteck hinzugefügt.
Auch wenn dieses Rechteck unsichtbar ist, ist es dennoch technisch sichtbar (d. h. visibility: visible
). Das Fehlen einer Füllung bedeutet jedoch, dass es nicht bemalt ist. Unser Bild sieht genauso aus. Tatsächlich funktioniert es immer noch genauso – das Klicken auf Leerzeichen löst immer noch keine Navigationsoperation aus. Wir müssen noch ein pointer-events
Attribut zu unserem a
-Element hinzufügen. Die Verwendung der visible
oder all
Werte funktioniert hier.
Jetzt kann das gesamte Bild Zeigerereignisse empfangen.
Die Verwendung eines bounding-box
würde die Notwendigkeit eines Phantomelements beseitigen. Alle Punkte innerhalb des Begrenzungsrahmens würden Zeigerereignisse erhalten, einschließlich des vom Pfad eingeschlossenen Leerraums. Aber noch einmal: pointer-events="bounding-box"
wird nicht allgemein unterstützt. Bis dahin können wir unbemalte Elemente verwenden.
Verwenden von pointer-events
beim Mischen von SVG und HTML
Ein weiterer Fall, in dem pointer-events
hilfreich sein können: die Verwendung von SVG innerhalb einer HTML-Schaltfläche.
In den meisten Browsern – Firefox und Internet Explorer 11 sind hier Ausnahmen – ist der Wert von event.target
ein SVG-Element anstelle unserer HTML-Schaltfläche. Fügen wir unserem öffnenden SVG-Tag pointer-events="none"
hinzu.
Wenn Benutzer jetzt auf unsere Schaltfläche klicken oder tippen, verweist das event.target
auf unsere button
.
Diejenigen, die sich mit DOM und JavaScript auskennen, werden feststellen, dass die Verwendung des Schlüsselworts function
anstelle einer Pfeilfunktion und this
anstelle von event.target
dieses Problem behebt. Die Verwendung von pointer-events="none"
(oder pointer-events: none;
in Ihrem CSS) bedeutet jedoch, dass Sie sich diese spezielle JavaScript-Eigenart nicht merken müssen.
Fazit
SVG unterstützt die gleiche Art von Interaktivität, die wir von HTML gewohnt sind. Wir können damit Diagramme erstellen, die auf Klicks oder Taps reagieren. Wir können verlinkte Bereiche erstellen, die nicht dem CSS- und HTML-Box-Modell entsprechen. Und mit dem Hinzufügen von pointer-events
können wir das Verhalten unserer SVG-Dokumente als Reaktion auf Benutzerinteraktionen verbessern.
Die Browserunterstützung für SVG pointer-events
ist robust. Jeder Browser, der SVG unterstützt, unterstützt die Eigenschaft für SVG-Dokumente und -Elemente. Bei Verwendung mit HTML-Elementen ist die Unterstützung etwas weniger robust. Es ist nicht in Internet Explorer 10 oder seinen Vorgängern oder einer Version von Opera Mini verfügbar.
Wir haben in diesem Stück nur an der Oberfläche von pointer-events
gekratzt. Für eine tiefergehende technische Behandlung lesen Sie die SVG-Spezifikation. MDN (Mozilla Developer Network) Web Docs bietet eine webentwicklerfreundlichere Dokumentation für pointer-events
, komplett mit Beispielen.