Search code examples
htmlcsssvgsafariclip-path

Trouble applying SVG clip-path with Safari


I'm trying to create a hexagonal border to a button. My strategy is to make the container element a couple of pixels larger than the button, and use the same clip-mask on both elements. The difference in size should create a border effect. This works well in Firefox and Chrome, but not in 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>

Without -webkit-clip-path the border was a rectangle in Safari. After adding it, the width of the resulting hexagon is much greater than in the other browsers. It appears the clip path is covering much more of the button than it should be. Is there any way to work around this so that it works well in Safari?

Firefox: Button in Firefox Safari: Button in Safari


Solution

  • Thanks to enxaneta who earned their bounty by showing me clip-path: polygon. Since this takes percentages, it's super easy to push out a hexagonal shape. Still curious about what was happening with the SVG-based path, but this simple change to my original code works great:

    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>