SVG/Tutorials/pointer-events
Sie verhindert mit einer Festlegung, dass …
- Klicks eine Aktion auslösen
- der cursor von auto auf pointer springt
- :hover und active-Zustände ausgelöst werden
- keine JavaScript click-Events gefeuert werden.
Inhaltsverzeichnis
pointer-events in SVG
Das SVG pointer-events-Präsentationsattribut ermöglicht es, Elemente gezielt von Interaktionen durch Maus und teilweise auch Tastatur auszuschließen.[1]
Am häufigsten verwendete Werte sind:
-
auto
, das Element verhält sich „ganz normal“ so, als obpointer-events
nicht gesetzt wäre, Voreinstellung -
none
, das Element reagiert nicht auf Interaktionen
Nur für SVG gültig sind:
-
visiblePainted
-
visibleFill
-
visibleStroke
-
visible
-
painted
-
fill
-
stroke
-
all
Dies ist insofern nützlich, wenn man in SVG ein Grafikobjekt aus mehreren Grundformen zeichnet und dies dann interaktiv, z.B. mit der Maus oder Tastatur auswählbar machen möchte.
Im Normalfall würde anfangs ein rect als Grundfläche für Hintergrundfarbe und Randlinie notiert werden. Darauf würden andere Grafikobjekte gezeichnet, die den Hintergrund verdecken. Um Mausaktionen bis zum untersten Element im Painting Stack durchzulassen, kann nun pointer-events="none"
auf den Kreis gesetzt werden:
<!--
The circle will always intercept the mouse event.
To change the stroke of the rect underneath you have
to click outside the circle
-->
<rect tabindex="1" x="5" y="5" height="10" width="10" />
<circle cx="10" cy="10" r="3" pointer-events="visiblePainted" />
<!--
The circle below will never catch a mouse event.
The rect underneath will change stroke whether you
are clicking on the circle or the rect itself
-->
<rect tabindex="2" x="20" y="5" height="10" width="10" />
<circle cx="25" cy="10" r="3" pointer-events="none" />
Dieses Beispiel zeigt zwei Kreise, die aber nur eine farbige Randlinie haben. Der eigentliche Kreis ist durchsichtig fill: transparent;
bzw. nicht gefüllt fill: none;
#ring {
fill: none;
stroke: gold;
}
#full {
fill: transparent;
stroke: gold;
pointer-events: visibleFill;
}
#full:hover {
stroke: #337599;
}
rect:hover {
stroke: #337599;
stroke-width: .5;
}
Der linke Kreis lässt in seiner Kreisform die Events durch; im rechten Kreis wird mit pointer-events: visibleFill;
nur die eigentliche Kreisfläche zum aktiven Element, obwohl sie transparent ist - ein :hover verändert die Farbe der Randlinie. Die Randlinie selbst lässt das :hover zum rect durch.
Fazit
Dieses Attribut stammt aus einer Zeit, in der SVG-Dokumente als Standalone-SVGs zum Teil eigene DropDown-Navigationen hatten. Hier konnte so das unterste rect zur Klickfläche werden, ohne dass danach gezeichneter Text die Klickfläche verdeckt.
In HTML haben Elemente, die Text enthalten, ja im Element selbst Möglichkeiten Rand und Hintergrund festzulegen.
pointer-events in CSS
Seit einiger Zeit ist dieses Attribut auch in CSS übernommen worden.[2]
Hier gibt es nur drei Werte:
-
auto
, das Element verhält sich „ganz normal“ so, als obpointer-events
nicht gesetzt wäre, Voreinstellung -
none
, das Element reagiert nicht auf Interaktionen -
inherit
, übernimmt den Wert des Elternelements
p.nicht_klickbar {
pointer-events: none;
}
p.beispiel {
border: thin solid #d5d5d5;
...
}
p.beispiel+p {
position: relative;
width: auto;
padding: 3em;
margin: 0 auto -7em;
top: -8em;
background-color: rgb(150 150 200 / 0.3);
color: #c32e04;
}
Die jeweils zweiten Absätze sind so verschoben, dass sie ihre Vorgänger überdecken. Im Normalfall ist deshalb der Text des darunterliegenden Elements nicht mit der Maus auswählbar. Wird für den überdeckenden Absatz festgelegt, dass dieser nicht auf Interaktionen mit der Maus reagieren soll, so hat dies zur Folge, dass nun der überdeckte Absatz mit der Maus bedienbar ist.
Andererseits sind Buttons, die mit pointer-events funktionslos geschaltet werden, mit der Tastatur noch auswählbar. Hier ist disabled die bessere Alternative![3]
Achtung!
Ire Aderinokun schrieb schon 2018 There’s no reason to use pointer-events for HTML elements.[4]
Anwendungsbeispiel
<fieldset>
<input id="tn-vielleicht" type="radio" name="teilnahme" value="0" checked="checked">
<label for="tn-vielleicht">vielleicht</label>
<input id="tn-nein" type="radio" name="teilnahme" value="-1">
<label for="tn-nein">nein</label>
<input id="tn-ja" type="radio" name="teilnahme" value="1">
<label for="tn-ja">ja</label>
</fieldset>
label{
position: absolute;
display: block;
left: 0;
top: 0;
width: 5em;
padding: .5em;
border: medium solid #c82f04;
text-align: center;
}
:checked + label {
z-index: 10;
pointer-events: none;
}
:checked + label + input + label {
pointer-events: none;
}
input {
display: none;
}
Das Beispiel zeigt einen Button, der 3 Status haben kann. Technisch handelt es sich um eine Gruppe von drei Radiobuttons. Mithilfe absoluter Positionierung werden die drei label
-Elemente übereinander positioniert.
Dasjenige Label, was zum ausgewählten Radiobutton gehört, wird durch die Angabe eines z-index sichtbar, für pointer-events werden sowohl dieses als auch das im Quelltext folgende label
-Element unempfänglich gemacht.
Siehe auch
Referenz:
Weblinks
- ↑ svgwg.org PointerEventsProperty (SVG 2)
- ↑ MDN: pointer-events
- ↑ pointer-events (davidwalsh.name)
- ↑ bitsofco.de: There’s no reason to use pointer-events for HTML elements von Ire Aderinokun, 2018