CSS:悬停在 SVG 组区域而不是渲染像素上,指针事件:边界框不能跨浏览器工作。如何解决
Posted
技术标签:
【中文标题】CSS:悬停在 SVG 组区域而不是渲染像素上,指针事件:边界框不能跨浏览器工作。如何解决【英文标题】:CSS :hover on SVG group area instead of rendered pixels, pointer-events: bounding-box not working cross browser. How to workaround 【发布时间】:2019-02-07 21:19:18 【问题描述】:我正在制作一些带有 CSS 动画的动画 SVG,这些动画会在悬停时触发。 我能够以我希望 Chrome 的方式悬停 SVG 动画,但我面临 Firefox 和 Safari 问题。
显然,应用于组 <g></g>
的 pointer-events
属性在此浏览器上的行为与在其他现代浏览器上的行为不同,至少在尝试将值设置为 bounding-box
时。
我在做
g
pointer-events: bounding-box;
但只有在实际的 <path>
元素悬停时才会触发悬停,而不是像我需要的那样整个组 <g>
。
Can I use 没有说明这一点,它提到 svgs 也支持这个属性。
下面有一个示例代码,供您查看我的一个 SVG 的外观。 在 chrome 上悬停主要包含组区域将触发悬停动画,在 Firefox 上实际路径(在本例中为图标行)需要悬停才能发生。
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<style>
g
pointer-events: bounding-box;
//not working on FF
#mobile:hover .flip
transform-origin:55% 50%;
-moz-transform-origin:55% 50%;
animation: flip_left 1.6s forwards;
@keyframes flip_left
0% transform: perspective(2000px) rotateY(90deg) skewY(-1deg)
30% transform:perspective(2000px) rotateY(-25deg) skewY(-0.8deg)
50% transform:perspective(2000px) rotateY(20deg) skewY(0.8deg)
70% transform:perspective(2000px) rotateY(-10deg) skewY(-0.8deg)
100% transform:perspective(2000px) rotateY(0deg)
</style>
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Mobile solutions</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="mobile" stroke="none" stroke- fill="none" fill-rule="evenodd">
<g id="MS_HP_Usecase_Based_Page-Desktop-2A" transform="translate(-766.000000, -418.000000)" stroke="#00A0DF" stroke->
<g id="Asset-5" transform="translate(766.000000, 418.000000)">
<g class="flip">
<rect id="Rectangle-path" stroke-linecap="round" stroke-linejoin="round" x="12.35" y="7.41" rx="2.03"></rect>
<circle id="Oval" stroke-linecap="round" stroke-linejoin="round" cx="20.01" cy="28.72" r="1.58"></circle>
<path d="M18.43,10.72 L21.48,10.72" id="Shape" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<circle id="Oval" cx="19.67" cy="19.67" r="19.04"></circle>
</g>
</g>
</g>
</svg>
我想找到一个解决方法,因为我想让这个动画跨浏览器工作。我希望最终让它也适用于 IE11 和 Edge。
谢谢,
【问题讨论】:
pointer-events: bounding-box;
你确定吗?不是有效值。请看MDN web docs pointer-events
@enxaneta 根据SVG2,它是一个有效值,但大多数浏览器尚未实现。通常的解决方法是定义一个覆盖所需区域的不可见<rect fill="none">
。然后为父组设置pointer-events:all
。
我在 Chrome 上开发此解决方案时发现了bounding-box
解决方案,但我没有意识到它根本不被所有浏览器支持。我现在觉得很傻。不管怎样,你们两个帮了我很多。我将实施解决方法并返回工作示例作为问题的答案。谢谢!
【参考方案1】:
所以pointer-events: bounding-box
似乎不受大多数浏览器的支持。
我在问题的 cmets 部分实施了@ccprog 建议的解决方法。
我在 svg 中添加了一个 <rect fill="none">
元素,它与 SVG 本身的尺寸相同。我为该元素添加了一个:hover
选择器和兄弟选择器~
以选择其内部包含flip
类的兄弟组。
参见 CSS:
#mobile-hover
visibility: visible;
pointer-events: visible;
#mobile-hover:hover ~ .group .flip
-moz-transform-origin:55% 50%;
-webkit-transform-origin: 55% 50%;
transform-origin:55% 50%;
-webkit-animation: flip_left 1.6s forwards;
animation: flip_left 1.6s forwards;
我发现我必须将pointer-events: visible
添加到rect
元素,这样它才能检测到:hover
。我添加了visibility: visible
作为pointer-events: visible
工作的要求。
在全新的 SVG 代码下方:
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="mobile-icon">
<style>
#mobile-hover
visibility: visible;
pointer-events: visible;
#mobile-hover:hover ~ .group .flip
-moz-transform-origin:55% 50%;
-webkit-transform-origin: 55% 50%;
transform-origin:55% 50%;
-webkit-animation: flip_left 1.6s forwards;
animation: flip_left 1.6s forwards;
@keyframes flip_left
0% transform: perspective(2000px) rotateY(90deg) skewY(-1deg)
30% transform:perspective(2000px) rotateY(-25deg) skewY(-0.8deg)
50% transform:perspective(2000px) rotateY(20deg) skewY(0.8deg)
70% transform:perspective(2000px) rotateY(-10deg) skewY(-0.8deg)
100% transform:perspective(2000px) rotateY(0deg)
</style>
<!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
<title>Mobile solutions</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="mobile" stroke="none" stroke- fill="none" fill-rule="evenodd" >
<rect fill="none" id="mobile-hover">
</rect>
<g id="MS_HP_Usecase_Based_Page-Desktop-2A" transform="translate(-766.000000, -418.000000)" stroke="#00A0DF" stroke- class="group">
<g id="Asset-5" transform="translate(766.000000, 418.000000)">
<g class="flip">
<rect id="Rectangle-path" stroke-linecap="round" stroke-linejoin="round" x="12.35" y="7.41" rx="2.03"></rect>
<circle id="Oval" stroke-linecap="round" stroke-linejoin="round" cx="20.01" cy="28.72" r="1.58"></circle>
<path d="M18.43,10.72 L21.48,10.72" id="Shape" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
<circle id="Oval" cx="19.67" cy="19.67" r="19.04"></circle>
</g>
</g>
</g>
</svg>
适用于 Chrome、Safari 和 Firefox,接下来我正在尝试测试 IE11 和 Edge。
非常感谢,
【讨论】:
以上是关于CSS:悬停在 SVG 组区域而不是渲染像素上,指针事件:边界框不能跨浏览器工作。如何解决的主要内容,如果未能解决你的问题,请参考以下文章
FF25 和 IE10 中的内联 SVG 上的 1 像素(或更少?亚像素?)边框,而不是 Chrome