使用 Safari 应用 SVG 剪辑路径时遇到问题

Posted

技术标签:

【中文标题】使用 Safari 应用 SVG 剪辑路径时遇到问题【英文标题】:Trouble applying SVG clip-path with Safari 【发布时间】:2019-05-06 11:23:09 【问题描述】:

我正在尝试为按钮创建六边形边框。我的策略是使容器元素比按钮大几个像素,并在两个元素上使用相同的clip-mask。大小的差异应该会产生边框效果。这适用于 Firefox 和 Chrome,但不适用于 Safari。

document.getElementById("button").addEventListener("click", function()alert("foo"); return false;);
div 
  width: 9rem;
  height: 8rem;
  position: relative;
  clip-path: url("#hexagon");
  -webkit-clip-path: url("#hexagon");
  background-color: #e2e3e5;


button 
  position: absolute;
  cursor: pointer;
  top: 2px;
  left: 2px;
  padding: calc(8rem * 0.1) calc(9rem * 0.2);
  width: calc(9rem - 4px);
  height: calc(8rem - 4px);
  clip-path: url("#hexagon");
  -webkit-clip-path: url("#hexagon");
  background-color: white;
  border: none;
<div id="div">
<button id="button">The button</button>
</div>

<svg   xmlns="http://www.w3.org/2000/svg">
  <defs>
    <clipPath id="hexagon" clipPathUnits="objectBoundingBox">
      <polygon points=".25 0, .75 0, 1 .5, .75 1, .25 1, 0 .5"/>
    </clipPath>
  </defs>
</svg>

如果没有-webkit-clip-path,边框在 Safari 中是一个矩形。添加后,生成的六边形的宽度比其他浏览器中的要大得多。看来剪辑路径覆盖的按钮比应有的要多得多。有什么办法可以解决这个问题,让它在 Safari 中运行良好?

火狐: 野生动物园:

【问题讨论】:

【参考方案1】:

您可以使用clip-path:polygon(),而不是使用clip-path: url() 我用你的分数乘以 10 并在x 上用 15 和在y 上用 5 抵消。 另外我正在缩放按钮,因为“边框”几乎不可见。

document.getElementById("button").addEventListener("click", function()alert("foo"); return false;);
div 
  width: 8rem;
  height: 6.6rem;
  position: relative;
  background-color: #ccc;
  -webkit-clip-path:polygon(40px 5px, 90px 5px, 115px 55px, 90px 105px,40px 105px, 15px 55px);
  clip-path:polygon(40px 5px, 90px 5px, 115px 55px, 90px 105px,40px 105px, 15px 55px);


button 
  position: absolute;
  cursor: pointer;
  text-align:center;
  width: 8rem;
  height: 6.6rem;
  -webkit-clip-path:polygon(40px 5px, 90px 5px, 115px 55px, 90px 105px,40px 105px, 15px 55px);
  clip-path:polygon(40px 5px, 90px 5px, 115px 55px, 90px 105px,40px 105px, 15px 55px);
  background-color: #fff;
  border:none;
  transform:scale(.97);
<div id="div">
<button id="button">The button</button>
</div>

另一种选择是使用 svg 元素而不是按钮。再次 - 对于六边形,我使用的是您的分数乘以 10。我个人更喜欢这个选项。

document.getElementById("button").addEventListener("click", function()alert("foo"); return false;);
#buttoncursor:pointer
<svg viewBox="-1 -1 102 102"  role="button">
 <polygon id="button" points="25 0, 75 0, 100 50, 75 100, 25 100, 0 50" stroke="#ccc" fill="none" pointer-events="all"/>
  <text x="50" y="50" text-anchor="middle" dominant-baseline="middle" font-size="14" pointer-events="none">the Button</text>
</svg>

您也可以使用以下几点:

document.getElementById("button").addEventListener("click", function()alert("foo"); return false;);
#buttoncursor:pointer
<svg viewBox = "-50 -50 100 100"  role="button">
  <polygon id="button" fill="none" stroke="#ccc" pointer-events="all" points = "48,0 24,41.57 -24,41.57 -48,0 -24,-41.57 24,-41.57 48,0" />

  <text text-anchor="middle" dominant-baseline="middle" font-size="14" pointer-events="none">the Button</text>
</svg>

【讨论】:

这看起来很有希望。我宁愿使用&lt;button&gt; 元素来避免对可访问性的任何担忧。可能aria-* 属性可以很好地处理事情,但我宁愿不要冒险。 我想你可能会这么说。这就是为什么我在 svg 元素中添加了 role="button"。 我想你可能会喜欢这个关于role属性的答案:***.com/questions/10403138/… 是的,我对此很熟悉,但我不知道 UA,尤其是屏幕阅读器之类的东西,是否能够正确地将 &lt;text&gt; 元素识别为标签等。我确实同意 SVG 是一种更清洁、更优雅的解决方案,但可能会与您的第一个解决方案一起使用。 clip-path: polygon() 实际上可以使用百分比,这比像素值更容易。【参考方案2】:

感谢 enxaneta 通过向我展示 clip-path: polygon 赢得了他们的赏金。由于这需要百分比,因此推出六边形非常容易。仍然对基于 SVG 的路径发生了什么感到好奇,但是对我的原始代码的这个简单更改效果很好:

document.getElementById("button").addEventListener("click", function() 
  alert("foo");
  return false;
);
div 
  width: 9rem;
  height: 8rem;
  position: relative;
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0% 50%, 25% 0);
  -webkit-clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0% 50%, 25% 0);
  background-color: #e2e3e5;


button 
  position: absolute;
  cursor: pointer;
  top: 2px;
  left: 2px;
  padding: calc(8rem * 0.1) calc(9rem * 0.2);
  width: calc(9rem - 4px);
  height: calc(8rem - 4px);
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0% 50%, 25% 0);
  -webkit-clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0% 50%, 25% 0);
  background-color: white;
  border: none;
<div id="div">
  <button id="button">The button</button>
</div>

【讨论】:

以上是关于使用 Safari 应用 SVG 剪辑路径时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

具有位置的元素:相对于 SVG 剪辑路径未在 Safari 中显示

Safari 不允许隐藏溢出的 svg 剪辑路径溢出容器

在动画上滴 SVG 剪辑路径

CSS - 剪辑路径 svg 在 Firefox 上不起作用

当引用为 css 剪辑路径属性时,SVG 剪辑路径的位置不正确

如何使用 SVG 形状进行图像剪辑?