创建反向剪切路径-CSS或SVG [英] Create a Reverse Clip-Path - CSS or SVG

查看:125
本文介绍了创建反向剪切路径-CSS或SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建本质上与CSS剪切路径相反的内容.使用剪切路径时,将剪切图像或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.

我希望这样,如果我剪切形状,则基本上是在最上层打一个孔并去除形状,而不是背景.这可能吗?我也愿意接受SVG解决方案,但是我是SVG的新手,所以请客气:)

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>

推荐答案

您可以将图像放在上方蓝色部分,然后在其上应用clip-path,结果将与如果您在蓝色部分内创建了一个孔以查看图像下方:

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>

更新

如果您想要一些不透明性,这里是一个想法,您必须使用clip-path复制内容(一个缺点):

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>

更新2

您可以考虑使用SVG来满足您的初始要求.只需使用SVG而不是将要具有遮罩的div即可.

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>

您还可以使用与背景相同的SVG:

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>

更新3(我在2020年提出的建议)

您可以使用CSS蒙版通过mask-composite

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆