Search code examples
csssvgfirefoxpseudo-class

SVG – :hover and links are not working in combination with clip-path and Firefox


For some reason, :hover and links are not working in combination with clip-path in Firefox. No problem with Chrome. I need clip-path to work. I know that it works without the attribute. However, it's not an option for me to remove this attribute.

Any idea why?


Simplified example:

<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
  <style>
    path {
      fill: blue;
    }

    path:hover {
      fill: red;
    }
  </style>
  <a target="_parent" href="/test">
    <path id="triangle" clip-path="url('#triangle-clip')" d="M150 0 L75 200 L225 200 Z">
      <title>Triangle</title>
    </path>
  </a>
  <clipPath id="triangle-clip">
    <use href="#triangle" />
  </clipPath>
</svg>


Solution

  • We need to break the recursion here that makes the whole thing invalid. I.e. in the version in the question the clip-path points to a <use> element that points to a <path> that has a clip-path that points to a <use> that points to a <path>...

    Here's one way i.e. apply the clip-path only to the path when it's a descendant of the <a> element. That's ignored by the <use> element because the selector crosses the shadow DOM boundary.

    Another way would be to replace the <use> element with a copy of the <path> its pointing to and remove the clip-path from that copy of the path, and so again fix the infinite recursion problem.

    <svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
      <style>
        path {
          fill: blue;
        }
    
        path:hover {
          fill: red;
        }
        a > path {
          clip-path: url('#triangle-clip');
        }
      </style>
      <a target="_parent" href="/test">
        <path id="triangle" d="M150 0 L75 200 L225 200 Z">
          <title>Triangle</title>
        </path>
      </a>
      <clipPath id="triangle-clip">
        <use href="#triangle" />
      </clipPath>
    </svg>