本文介绍了创建反向剪辑路径 - CSS 或 SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试创建本质上与 CSS 剪辑路径相反的内容.使用 clip-path 时,图像或 div 会被剪裁,以便仅保留您指定的形状,而背景的其余部分将被有效删除.
我希望这样,如果我剪辑一个形状,它基本上会在最上层打一个洞并移除形状,而不是背景.这可能吗?我也愿意接受 SVG 解决方案,但我是 SVG 的新手,所以请善待:)
基本上,在下面的代码中,我有一个绝对位于红色方块内的蓝色方块,并希望能够从蓝色方块中冲压出一个形状,以便下面的红色层显示该形状曾经所在的位置.实际上会有一个图像作为背景层,所以我不能接受模仿我想要的但实际上并没有打出形状的伪效果.
任何帮助都会很棒!
codepen:https://codepen.io/emilychews/pen/GQmyqx
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:红色;}#内盒 {宽度:100%;高度:100%;背景:蓝色;顶部:0;左:0;位置:绝对;}
<div id="innerbox"></div>
解决方案
您可以将图像上方蓝色部分,然后在其上应用 clip-path
结果将与您在蓝色部分内创建一个孔以查看图像下方一样:
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:蓝色;}#内盒 {宽度:100%;高度:100%;背景:网址(https://lorempixel.com/400/400/)中心/封面;顶部:0;左:0;位置:绝对;z-索引:1;剪辑路径:多边形(10% 10%、10% 90%、90% 50%);}
<div id="innerbox"></div>
另一个想法是考虑多个背景,您将获得比剪辑路径更好的支持,并且代码更少:
body {高度:100vh;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:线性渐变(到右下角,透明 49%,蓝色 50%)底部/100% 60%,线性渐变(到右上角,透明 49%,蓝色 50%)顶部/100% 60%,线性渐变(蓝色,蓝色)左/20% 100%,网址(https://lorempixel.com/400/400/)中心/封面;背景重复:不重复;}
更新
如果你想要一些不透明度,这里有一个想法,你必须使用 clip-path
复制内容(一个缺点):
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:蓝色;}#innerbox,#innerbox-2 {宽度:100%;高度:100%;背景:网址(https://lorempixel.com/400/400/)中心/封面;顶部:0;左:0;位置:绝对;z-索引:2;}#内盒 {/* 如果你最初计划有 x opacity 所以你需要在这里设置 1-x */不透明度:0.4;}#innerbox-2 {z-索引:1;剪辑路径:多边形(10% 10%、10% 90%、90% 50%);动画:动画 5s 线性交替无限;}@keyframes 动画 {从 {剪辑路径:多边形(10% 10%、10% 90%、90% 50%);}到 {剪辑路径:多边形(20% 50%、90% 50%、80% 10%);}}
<div id="innerbox"><h1>标题</h1><p>一些内容</p>
<div id="innerbox-2"><h1>标题</h1><p>一些内容</p>
更新 2
您可以考虑使用 SVG 来满足您的初始需求.只需使用 SVG 而不是 div,您将在其中使用蒙版.
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:蓝色;背景:网址(https://lorempixel.com/400/400/)中心/封面;}#内盒 {宽度:100%;高度:100%;顶部:0;左:0;位置:绝对;z-索引:1;}
<svg viewBox="0 0 200 200" id="innerbox"preserveAspectRatio="none"><mask id="洞"><rect width="100%" height="100%" fill="white"/><!-- 孔定义了一个多边形--><polygon points="20,20 20,180 180,100 " fill="black"/></掩码></defs><!-- 创建一个矩形,用颜色填充它并应用上面的蒙版--><rect fill="blue" width="100%" height="100%" mask="url(#hole)"/></svg>
您也可以使用相同的 SVG 作为背景:
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:蓝色;背景:网址(https://lorempixel.com/400/400/)中心/封面;}#内盒 {宽度:100%;高度:100%;顶部:0;左:0;位置:绝对;z-索引:1;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"preserveAspectRatio="none"><defs><mask id="hole"><rect width="100%" height="100%" fill="white"/> <polygon points="20,20 20,180 180,100" 填充="黑色"/></mask></defs><rect fill="blue" width="100%" height="100%" mask="url(%23hole)"/><;/svg>');}
<div id="innerbox"></div>
更新 3(我在 2020 年推荐的内容)
mask-composite
你可以使用 CSS 遮罩来获得你想要的效果
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:网址(https://lorempixel.com/400/400/)中心/封面;}#内盒 {宽度:100%;高度:100%;顶部:0;左:0;位置:绝对;-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%;mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%;背景:蓝色;}
<div id="innerbox"></div>
与使用相同形状的倒置版
body {宽度:100%;高度:100vh;填充:0;边距:0;显示:弹性;}#盒子 {保证金:自动;位置:相对;宽度:33%;高度:200px;背景:网址(https://lorempixel.com/400/400/)中心/封面;}#内盒 {宽度:100%;高度:100%;顶部:0;左:0;位置:绝对;-webkit-掩码:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"preserveAspectRatio="none"><多边形点="20,20 20,180 180,100" 填充="黑色"/></svg>') 0/100% 100%,线性梯度(#fff,#fff);-webkit-mask-composite:destination-out;面具:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"preserveAspectRatio="none"><多边形点="20,20 20,180 180,100" 填充="黑色"/></svg>') 0/100% 100%,线性梯度(#fff,#fff);面具复合:排除;背景:蓝色;}
<div id="innerbox"></div>
I'm trying to create what is in essence the reverse of a CSS clip-path. When using clip-path, an image or div is clipped so that only the shape you specify remains and the rest of the background is effectively deleted.
I would like it so that if I clip a shape it basically punches a hole in the upper most layer and removes the shape, not the background. Is this possible? I'd also be open to an SVG solution, but I am new to SVG so be kind :)
Basically, in the code below I have a blue square positioned absolutely inside a red square and want to be able to punch a shape out of the blue square so the red layer below shows through where the shape used to be. In reality there will an image as the background layer, so I can't accept a pseudo effect that mimics what I want but doesn't actually punch the shape out.
Any assistance would be amazing!
codepen: https://codepen.io/emilychews/pen/GQmyqx
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: red;
}
#innerbox {
width: 100%;
height: 100%;
background: blue;
top: 0;
left: 0;
position: absolute;
}
<div id="box">
<div id="innerbox"></div>
</div>
解决方案
You can put the image above the blue part and you apply the clip-path
on it then the result will be the same as if you have created a hole inside the blue part to see the image below:
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: blue;
}
#innerbox {
width: 100%;
height: 100%;
background: url(https://lorempixel.com/400/400/) center/cover;
top: 0;
left: 0;
position: absolute;
z-index:1;
clip-path:polygon(10% 10%, 10% 90%, 90% 50%);
}
<div id="box">
<div id="innerbox"></div>
</div>
Another idea is to consider multiple background and you will have better support than clip-path and also less of code:
body {
height: 100vh;
margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background:
linear-gradient(to bottom right,transparent 49%,blue 50%) bottom/100% 60%,
linear-gradient(to top right,transparent 49%,blue 50%) top/100% 60%,
linear-gradient(blue,blue) left/20% 100%,
url(https://lorempixel.com/400/400/) center/cover;
background-repeat:no-repeat;
}
<div id="box">
</div>
UPDATE
If you want some opacity, here is an idea where you have to duplicate the content using clip-path
(a drawback):
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: blue;
}
#innerbox,#innerbox-2 {
width: 100%;
height: 100%;
background: url(https://lorempixel.com/400/400/) center/cover;
top: 0;
left: 0;
position: absolute;
z-index:2;
}
#innerbox {
/* if you initially planned to have x opacity so you need to set 1-x here*/
opacity:0.4;
}
#innerbox-2 {
z-index:1;
clip-path:polygon(10% 10%, 10% 90%, 90% 50%);
animation:animate 5s linear alternate infinite;
}
@keyframes animate {
from {
clip-path:polygon(10% 10%, 10% 90%, 90% 50%);
}
to {
clip-path:polygon(20% 50%, 90% 50%, 80% 10%);
}
}
<div id="box">
<div id="innerbox">
<h1>Title</h1>
<p>Some content</p>
</div>
<div id="innerbox-2">
<h1>Title</h1>
<p>Some content</p>
</div>
</div>
UPDATE 2
You can consider SVG to do your initial requirement. Simply use an SVG instead of a div where you will have a mask.
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: blue;
background: url(https://lorempixel.com/400/400/) center/cover;
}
#innerbox {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
z-index:1;
}
<div id="box">
<svg viewBox="0 0 200 200" id="innerbox" preserveAspectRatio="none">
<defs>
<mask id="hole">
<rect width="100%" height="100%" fill="white"/>
<!-- the hole defined a polygon -->
<polygon points="20,20 20,180 180,100 " fill="black"/>
</mask>
</defs>
<!-- create a rect, fill it with the color and apply the above mask -->
<rect fill="blue" width="100%" height="100%" mask="url(#hole)" />
</svg>
</div>
You can also use the same SVG as background:
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: blue;
background: url(https://lorempixel.com/400/400/) center/cover;
}
#innerbox {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
z-index:1;
background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><defs><mask id="hole"><rect width="100%" height="100%" fill="white"/> <polygon points="20,20 20,180 180,100 " fill="black"/></mask></defs><rect fill="blue" width="100%" height="100%" mask="url(%23hole)" /></svg>');
}
<div id="box">
<div id="innerbox"></div>
</div>
Update 3 (what I recommend in 2020)
You can use CSS mask to get the effect you want with mask-composite
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
}
#innerbox {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%;
mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%;
background:blue;
}
<div id="box">
<div id="innerbox"></div>
</div>
And the inverted version using the same shape
body {
width: 100%;
height: 100vh;
padding: 0; margin: 0;
display: flex;
}
#box {
margin: auto;
position: relative;
width: 33%;
height: 200px;
background: url(https://lorempixel.com/400/400/) center/cover;
}
#innerbox {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
-webkit-mask:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%,
linear-gradient(#fff,#fff);
-webkit-mask-composite:destination-out;
mask:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="none"><polygon points="20,20 20,180 180,100 " fill="black"/></svg>') 0/100% 100%,
linear-gradient(#fff,#fff);
mask-composite:exclude;
background:blue;
}
<div id="box">
<div id="innerbox"></div>
</div>
这篇关于创建反向剪辑路径 - CSS 或 SVG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!