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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
In your case clip-path
does nothing, so I just removed it. ANd it's important to add @namespace
.
@namespace svg url(http://www.w3.org/2000/svg);
svg|a path {
fill: blue;
}
svg|a:hover path {
fill: red;
}
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<a href="/test">
<path id="triangle" d="M150 0 L75 200 L225 200 Z">
<title>Triangle</title>
</path>
</a>
</svg>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I noticed that if you open developer tools in Firefox you will see that you have a shadow-root (closed)
whereas in Chrome you do not. That could possibly be why your :hover
Pseudo-class isn't executing.
https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode
CodePudding user response:
As @Robert Longson has pointed out your initial code has a recursion issue.
Essentially, you are clipping an svg path (triangle) by itself (... that still has to be defined by itself) – resulting in the exact same shape as the 'unclipped' version.
However, since you already used the <use>
element, reordering your path and clipping path definitions - avoiding unnessesary recursions – might still simplify your app's code.
<svg xmlns="http://www.w3.org/2000/svg" height="210" width="400">
<clipPath id="triangle-clip">
<path id="triangle-path" d="M150 0 L75 200 L225 200 Z" />
</clipPath>
<style>
.link-content {
fill: blue;
clip-path: url('#triangle-clip');
}
a:hover .link-content{
fill: red;
}
</style>
<a class="link" target="_parent" href="/test">
<title>Triangle</title>
<use class="link-content" href="#triangle-path" />
</a>
</svg>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>