Click Only Through Holes In Svg Mask
Solution 1:
There are several aspects to this problem. First, you are right the behavior of masks and clip-paths is different in relation to hit-testing.
A clip path is a geometric boundary, and a given point is clearly either inside or outside that boundary; thus, pointer events must be captured normally over the rendered areas of a clipped element, but must not be captured over the clipped areas... By contrast, a mask is not a binary transition, but a pixel operation, and different behavior for fully transparent and almost-but-not-fully-transparent may be confusingly arbitrary; as a consequence, for elements with a mask applied, pointer events must still be captured even in areas where the mask goes to zero opacity.
Second, a clip-path is a geometric shape, but just like all paths, it might contain holes. Instead of three <rect>
s, you can use one <path>
with three subpaths, as long as the clip-rule
makes sure the subpaths inside get cut out of the surrounding shape.
Third, if the pointer-events
property is applied to an <svg>
element in a HTML context, its behavior becomes...strange. Any other value than pointer-events: none
on the <svg>
element lead to the whole bounding box receiving events - a behavior proposed for HTML elements, but currently not part of any spec.
The solution here is to set pointer-events: none
on the <svg>
element, and then to reverse that with pointer-events: painted
on the child <rect>
element.
button, svg {
position:absolute;
width:400px;
height:400px
}
button {
background: #0000ff;
cursor: pointer;
}
button:hover {
background: #008800;
}
svg {
pointer-events: none;
}
.over {
fill: #000;
clip-path: url(#clip);
pointer-events: painted;
}
<button></button><svgxmlns="http://www.w3.org/2000/svg"height="400"width="400"><defs><clipPathid="clip"clip-rule="evenodd"><pathd="M 20 20 h 360 v 360 h -360 z
M 40 40 v 40 h 40 v -40 z
M 200 290 v 40 h 40 v -40 z" /></clipPath></defs><recty="0"x="0"height="400"width="400"class="over" /></svg>
Solution 2:
Clip masks are useful for cropping parts out of complicated objects, but if you're just working with blocks of solid colour then maybe it would be just as easy to create shapes that already have holes in them.
I've added an example below. Does this help?
<svgwidth="400"heoght="200"viewBox="0 0 400 200"><textx="100"y="100"text-anchor="middle"alignment-baseline="middle"onclick="alert('Hello!')"style="cursor:pointer">Click me</text><textx="300"y="100"text-anchor="middle"alignment-baseline="middle"onclick="alert('Hello?')"style="cursor:pointer">Not me</text><pathd="M20 20 180 20 180 180 20 180ZM60 60 60 140 140
140 140 60Z"fill="#3a6"fill-opacity="0.7"fill-rule="nonzero"/><pathd="M220 20 380 20 380 180 220 180Z"fill="#f20"fill-opacity="0.7"/></svg>
Post a Comment for "Click Only Through Holes In Svg Mask"