在Safari中使用SVG剪切路径遇到问题

3

我正在尝试为按钮创建一个六边形边框。我的策略是使容器元素比按钮大几个像素,并在两个元素上使用相同的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 width="0" height="0" 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中表现良好?
火狐:Button in Firefox Safari:Button in Safari
2个回答

5

使用 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;});
#button{cursor:pointer}
<svg viewBox="-1 -1 102 102" width="6rem" 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;});
#button{cursor:pointer}
<svg viewBox = "-50 -50 100 100" width="6rem" 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>


这看起来很有前途。为了避免任何辅助功能方面的问题,我宁愿使用 <button> 元素。也许 aria-* 属性可以很好地处理问题,但我不想冒任何风险。 - miken32
我想你可能会这么说。这就是为什么我已经在SVG元素中添加了[role="button"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role)。 - enxaneta
我认为您可能会喜欢这篇关于role属性的答案:https://dev59.com/Jmkv5IYBdhLWcg3wtTK7 - enxaneta
1
是的,我熟悉这个,但我不知道UAs,特别是像屏幕阅读器之类的东西,能否正确地将<text>元素识别为标签等。我确实同意SVG是更清洁和更优雅的解决方案,但可能会选择你的第一个方案。 - miken32
2
clip-path: polygon() 实际上可以使用百分比,这使得事情比像素值更容易。 - miken32

1
感谢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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接