Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my clip-path not working when it's source is an svg?

Tags:

css

svg

I'm following the mozilla documentation on using css clip-path property to apply an svg clipPath to an HTMLElement. But for some reason, it doesn't work for me, not in div's and not in images.

In the documentation, it says you can easily clip an element with this code:

<style>.target { clip-path: url(#c1); }</style>
<svg:svg height="0">
  <svg:clipPath id="c1" clipPathUnits="objectBoundingBox">
    <svg:circle cx="0.25" cy="0.25" r="0.25" id="circle"/>
    <svg:rect x="0.5" y="0.2" width="0.5" height="0.8"/>
  </svg:clipPath>
</svg:svg>

And I've tried that, but it doesn't work. The clip-path property works with predefined methods like polygon() and ellipse() but it won't work with a linked svg.

I made a JSFiddle illustrating my problem, hopefully you can find my mistake :)

like image 287
undefined Avatar asked Dec 14 '22 17:12

undefined


2 Answers

Put your clipPath in defs tags. Use foreignObject to import the HTML elements that needs to be clipped and apply inline clip-path for maximum browser support.

#kitten {
  width: 250px;
}
#kittenReplica {
  width: 250px;
  height: 187.5px;
  background-color: lightblue;
}
<svg width="500px" height="187.5px">
  <defs>
    <clipPath id="path" clipPathUnits="objectBoundingBox">
      <circle cx="0.25" cy="0.25" r="0.25" id="circle" />
      <rect x="0.5" y="0.2" width="0.5" height="0.8" />
    </clipPath>
  </defs>
  <foreignObject clip-path="url(#path)" width="50%" height="100%">
    <img src="http://i.imgur.com/tzPv43g.jpg" id="kitten" class="clipped" />
  </foreignObject>
  <foreignObject x="250" clip-path="url(#path)" width="50%" height="100%">
    <div id="kittenReplica" class="clipped"></div>
  </foreignObject>
</svg>
like image 187
Weafs.py Avatar answered Dec 29 '22 01:12

Weafs.py


Your problem was that you were using elements with the "svg" namespace prefix, but not defining the svg namespace. If you remove the "svg:" from each element, it works.

For example, change <svg:svg ...> to <svg ...>.

If you look at the original Firefox example you copied from, you will see that the svg namespace is defined in the <html> element: xmlns:svg="http://www.w3.org/2000/svg".

Below is a version of that sample that works on Firefox and Chrome.

And here is an updated version of your fiddle that works.

body {
    background:#ccc;
    font-size:30px;
}

p {
    width:300px;
    border:1px solid black;
    display:inline-block;
    margin:1em;
}

b {
    outline:1px dotted blue;
}

.target {
    -webkit-clip-path: url(#c1);
    clip-path: url(#c1);
}
<p class="target" style="background:lime;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
</p>
 
<img src="http://i.imgur.com/tzPv43g.jpg" id="kitten" class="target" />


<svg height="0">
    <defs>
        <clipPath id="c1" clipPathUnits="objectBoundingBox">
            <circle cx="0.25" cy="0.25" r="0.25" id="circle"/>
            <rect x="0.5" y="0.2" width="0.5" height="0.8"/>
        </clipPath>
    </defs>
</svg>
like image 26
Paul LeBeau Avatar answered Dec 29 '22 00:12

Paul LeBeau