clip-path svg 适用于图像,但不适用于 div
clip-path svg works on image, but not on div
在 MDN 上有一个关于如何在图像上使用 clip-path svg 的示例。相同的剪辑路径似乎不适用于 div
元素。有人可以澄清一下吗:
- 为什么此代码无法按预期工作
- 一种使 svg 剪辑路径在 div
上工作的方法
示例代码 (based on MDN docs) 裁剪图像
#clipped {
clip-path: url(#cross);
}
<img id="clipped" src="https://mdn.mozillademos.org/files/12668/MDN.svg"
alt="MDN logo">
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
div 上的相同剪辑路径(这似乎不起作用)
#clipped {
width: 100px;
height: 100px;
background: black;
clip-path: url(#cross);
}
<div id="clipped"></div>
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
Clip-path
不继承。 Establishing a new clipping path: the ‘clipPath’ element W3C
因此,我们不会通过将clip-path
应用于父块
来切割子元素
最好使用 svg <image>
标签而不是 <img>
并对其应用 clip-path
使用div作为自适应容器
.wrapped {
width:25%;
height:25%;
}
#img1 {
clip-path:url(#cross);
}
<div class="wrapped">
<svg viewBox="0 0 250 250">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
<image id="img1" width="100%" height="100%" xlink:href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"/>
</svg>
</div>
正如@enxaneta 所指出的,这完全是一个大小问题。如果增加 div 的大小,您将看到效果:
#clipped {
width: 300px;
height: 200px;
background: black;
clip-path: url(#cross);
}
<div id="clipped"></div>
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
或者您可以使用 mask
来获得动态效果。每个角有 4 个白色矩形和白色的技巧意味着 使其可见
.box {
width: 100px;
height: 100px;
margin:5px;
background: linear-gradient(red,blue);
-webkit-mask:
linear-gradient(white,white) top left,
linear-gradient(white,white) top right,
linear-gradient(white,white) bottom left,
linear-gradient(white,white) bottom right;
-webkit-mask-size:40% 40%;
-webkit-mask-repeat:no-repeat;
-mask:
linear-gradient(white,white) top left,
linear-gradient(white,white) top right,
linear-gradient(white,white) bottom left,
linear-gradient(white,white) bottom right;
mask-size:40% 40%;
mask-repeat:no-repeat;
}
<div class="box"></div>
<div class="box" style="width:200px;height:200px;"></div>
您的问题的解决方案是使用 clipPathUnits="objectBoundingBox"
并构建大小介于 0 和 1 之间的剪切路径,如下所示:
#clipped {
margin:1em;
width: 100px;
height: 100px;
background: black;
display:inline-block;
clip-path: url(#cross);
}
#clipped.big{
width: 200px;
height: 200px;
}
<div id="clipped"></div>
<div id="clipped" class="big"></div>
<svg viewBox="0 0 1 1">
<clipPath id="cross" clipPathUnits="objectBoundingBox">
<rect y="0" x="0" width=".4" height=".4"/>
<rect y="0.6" x="0" width=".4" height=".4"/>
<rect y="0" x="0.6" width=".4" height=".4"/>
<rect y="0.6" x="0.6" width=".4" height=".4"/>
</clipPath>
</svg>
在 MDN 上有一个关于如何在图像上使用 clip-path svg 的示例。相同的剪辑路径似乎不适用于 div
元素。有人可以澄清一下吗:
- 为什么此代码无法按预期工作
- 一种使 svg 剪辑路径在 div 上工作的方法
示例代码 (based on MDN docs) 裁剪图像
#clipped {
clip-path: url(#cross);
}
<img id="clipped" src="https://mdn.mozillademos.org/files/12668/MDN.svg"
alt="MDN logo">
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
div 上的相同剪辑路径(这似乎不起作用)
#clipped {
width: 100px;
height: 100px;
background: black;
clip-path: url(#cross);
}
<div id="clipped"></div>
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
Clip-path
不继承。 Establishing a new clipping path: the ‘clipPath’ element W3C
因此,我们不会通过将clip-path
应用于父块
最好使用 svg <image>
标签而不是 <img>
并对其应用 clip-path
使用div作为自适应容器
.wrapped {
width:25%;
height:25%;
}
#img1 {
clip-path:url(#cross);
}
<div class="wrapped">
<svg viewBox="0 0 250 250">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
<image id="img1" width="100%" height="100%" xlink:href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"/>
</svg>
</div>
正如@enxaneta 所指出的,这完全是一个大小问题。如果增加 div 的大小,您将看到效果:
#clipped {
width: 300px;
height: 200px;
background: black;
clip-path: url(#cross);
}
<div id="clipped"></div>
<svg height="0" width="0">
<defs>
<clipPath id="cross">
<rect y="110" x="137" width="90" height="90"/>
<rect x="0" y="110" width="90" height="90"/>
<rect x="137" y="0" width="90" height="90"/>
<rect x="0" y="0" width="90" height="90"/>
</clipPath>
</defs>
</svg>
或者您可以使用 mask
来获得动态效果。每个角有 4 个白色矩形和白色的技巧意味着 使其可见
.box {
width: 100px;
height: 100px;
margin:5px;
background: linear-gradient(red,blue);
-webkit-mask:
linear-gradient(white,white) top left,
linear-gradient(white,white) top right,
linear-gradient(white,white) bottom left,
linear-gradient(white,white) bottom right;
-webkit-mask-size:40% 40%;
-webkit-mask-repeat:no-repeat;
-mask:
linear-gradient(white,white) top left,
linear-gradient(white,white) top right,
linear-gradient(white,white) bottom left,
linear-gradient(white,white) bottom right;
mask-size:40% 40%;
mask-repeat:no-repeat;
}
<div class="box"></div>
<div class="box" style="width:200px;height:200px;"></div>
您的问题的解决方案是使用 clipPathUnits="objectBoundingBox"
并构建大小介于 0 和 1 之间的剪切路径,如下所示:
#clipped {
margin:1em;
width: 100px;
height: 100px;
background: black;
display:inline-block;
clip-path: url(#cross);
}
#clipped.big{
width: 200px;
height: 200px;
}
<div id="clipped"></div>
<div id="clipped" class="big"></div>
<svg viewBox="0 0 1 1">
<clipPath id="cross" clipPathUnits="objectBoundingBox">
<rect y="0" x="0" width=".4" height=".4"/>
<rect y="0.6" x="0" width=".4" height=".4"/>
<rect y="0" x="0.6" width=".4" height=".4"/>
<rect y="0.6" x="0.6" width=".4" height=".4"/>
</clipPath>
</svg>