我想仅使用CSS3制作透明的半圆形切出的形状。唯一的要求是,构成形状的所有元素都必须是黑色或透明的。

我不能使用上面带有白色圆圈的黑色矩形,因为半个圆圈必须是透明的,并且可以让背景透彻显示。

所需形状:



评论

这是“做我的作业”的问题吗? hmmmmm

为什么不想使用白色圆圈?

只需将上面的图片用作背景图片即可!从技术上讲只是css3

我不想使用白色圆圈,因为我希望形状是透明的。

#1 楼

可以使用CSS :after伪属性来实现,例如:




 body {
  background: green;
}

.rect {
  height: 100px;
  width: 100px;
  background: rgba(0, 0, 0, 0.5);
  position: relative;
  margin-top: 100px;
  margin-left: 100px;
}

.circle {
  display: block;
  width: 100px;
  height: 50px;
  top: -50px;
  left: 0;
  overflow: hidden;
  position: absolute;
}

.circle:after {
  content: '';
  width: 100px;
  height: 100px;
  -moz-border-radius: 100px;
  -webkit-border-radius: 100px;
  border-radius: 100px;
  background: rgba(0, 0, 0, 0);
  position: absolute;
  top: -100px;
  left: -40px;
  border: 40px solid rgba(0, 0, 0, 0.5);
} 

 <div class="rect">&nbsp;<span class="circle"></span></div> 





在JSFiddle上查看

评论


这是非常好的。我有点困惑它是如何工作的,但是在清除溢出后很明显:隐藏在.circle中:jsfiddle.net/thirtydot/FcaVX/3

–thirtydot
2011-12-14 11:57

接近完美。现在只需将所有rgba(0,0,0,0.5)颜色更改为#000。瞧!好运动,OP,好运动

– iGbanam
2011-12-14 11:57

谢谢!太棒了。

–user852974
2011-12-14 12:01

#2 楼

您可以使用阴影阴影来制作透明的切出圆圈:




 body {
  background: url(http://i.imgur.com/qi5FGET.jpg) no-repeat;
  background-size: cover;
}
div {
  display: inline-block;
  width: 300px; height: 300px;
  position: relative;
  overflow: hidden;
}
div:before {
  content: '';
  position: absolute;
  bottom: 50%;
  width: 100%; height: 100%;
  border-radius: 100%;
  box-shadow: 0px 300px 0px 300px #000;
}
.transparent {
  opacity: 0.5;
} 

 <div></div>
<div class="transparent"></div> 







这可以响应百分比长度:




 body {
  background: url(http://lorempixel.com/output/people-q-c-640-480-1.jpg) no-repeat;
  background-size: cover;
}
div {
  width: 40%; height: 300px;
  position: relative;
  overflow: hidden;
}
div:before {
  content: '';
  position: absolute;
  bottom: 50%;
  width: 100%; height: 100%;
  border-radius: 100%;
  box-shadow: 0px 300px 0px 300px #000;
}
.transparent {
  opacity: 0.5;
} 

 <div class="transparent"></div> 




#3 楼

使用SVG:

这里是使用SVG的替代解决方案(尽管您尚未对其进行标记)。使用SVG的优点是:


与径向渐变相比,它具有更好的浏览器支持。
SVG可以支持形状内的图像,这与框阴影方法不同。
/>
<= IE8不支持SVG,而box-shadow支持,但可以提供备用。




 svg {
  height: 150px;
  width: 150px;
}
polygon {
  fill: black;
}

/* Just for demo */

body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
} 

 <!-- Sample 1 - Using Clip Path -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
  <defs>
    <clipPath id='clipper'>
      <path d='M0,0 a50,50 0 1,0 100,0 l 0,100 -100,0' />
    </clipPath>
  </defs>
  <polygon points='0,0 100,0 100,100 0,100' clip-path='url(#clipper)' />
</svg>

<!-- Sample 2 - Using Path -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
  <pattern id='bg' width='100' height='100' patternUnits='userSpaceOnUse'>
    <image xlink:href='http://lorempixel.com/100/100/nature/1' height='100' width='100' />
  </pattern>
  <path d='M0,0 a50,50 0 1,0 100,0 l 0,100 -100,0 0,-100' fill='url(#bg)' />
</svg> 






使用CSS:

CSS也具有clip-path规范,我们可以尝试以下代码段。




 .shape {
  position: relative;
  width: 100px;
  height: 100px;
  background-color: purple;
}
.shape:after {
  position: absolute;
  content: '';
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
  background: white;
  -webkit-clip-path: ellipse(50% 20% at 50% 0%);
  clip-path: ellipse(50% 20% at 50% 5%);
}

.shape.image{
  background: url(http://lorempixel.com/100/100);
}

#shape-2 {
  width: 100px;
  height: 100px;
  background-color: purple;
  -webkit-clip-path: ellipse(50% 20% at 50% 20%);
  clip-path: ellipse(50% 20% at 50% 20%);
}

/* Just for demo */

.shape{
  float: left;
  margin: 20px;
}
#shape-2 {
  margin: 150px 20px 0px;
} 

 <div class="shape"></div>
<div class="shape image"></div>
<br/>

<div id="shape-2"></div> 





但是与SVG剪切路径不同,纯CSS版本(即,不使用内联或外部SVG)似乎无法支持path。它仅支持形状,因此,在这种情况下,如果直接在父级上使用clip-path,它将仅生成一个椭圆(如代码片段中所示)。为了克服这个问题,我们必须将剪切路径放在子对象(或伪元素)上,这意味着剪切的区域将不是透明的。


使用Canvas:

同样可以使用Canvas来完成。 Canvas命令与SVG非常相似,其优势也非常相似。但是,Canvas基于栅格,因此无法像SVG那样缩放。




 window.onload = function() {
  /* Canvas example with path */
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = 'http://lorempixel.com/150/300';
    ctx.beginPath();
    ctx.moveTo(110, 0);
    ctx.arc(60, 0, 50, 0, 3.14, false);
    ctx.lineTo(10, 145);
    ctx.lineTo(110, 145);
    ctx.closePath();
    ctx.fill();
    /* Use below for using image as a fill */
    /*img.onload = function(){
        var ptrn = ctx.createPattern(img,'no-repeat');
        ctx.fillStyle = ptrn;
        ctx.fill();
    }*/
  }

  /* Canvas example with clip path */
  var canvasClip = document.getElementById('canvas-clip');
  if (canvasClip.getContext) {
    var ctxClip = canvasClip.getContext('2d');
    ctxClip.beginPath();
    ctxClip.moveTo(10, 145);
    ctxClip.lineTo(10, 0);
    ctxClip.arc(60, 0, 50, 0, Math.PI * 2, true);
    ctxClip.lineTo(110, 145);
    ctxClip.lineTo(10, 145);
    ctxClip.clip();
    ctxClip.fillStyle = 'tomato';
    ctxClip.fill();
  }
} 

 canvas {
  height: 150px;
  width: 300px;
}
/* Just for demo */

body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
} 

 <canvas id='canvas'></canvas>
<canvas id='canvas-clip'></canvas> 






使用口罩:

也可以使用CSS(或)SVG蒙版来创建此形状。 CSS掩码的支持非常差,目前仅在基于Webkit的浏览器中工作,而SVG掩码具有更好的支持,并且应在IE9 +中工作。




 /* CSS Mask */

.shape {
  width: 150px;
  height: 150px;
  background-color: black;
  -webkit-mask-image: radial-gradient(circle closest-corner at 50% 0%, transparent 98%, white 99%);
  mask-image: radial-gradient(circle closest-corner at 50% 0%, transparent 98%, white 99%);
}

/* End of CSS Mask */

svg {
  height: 150px;
  width: 150px;
}
polygon#shape {
  fill: black;
  mask: url(#masker);
}
/* Just for demo */

body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
} 

 <!-- CSS Mask -->

<div class='shape'></div>

<!-- SVG Mask -->
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
  <defs>
    <mask id='masker' x='0' y='0' width='100' height='100'>
      <polygon points='0,0 100,0 100,100 0,100' fill='#fff' />
      <circle r='50' cx='50' cy='0' fill='#000' />
    </mask>
  </defs>
  <polygon points='0,0 100,0 100,100 0,100' id='shape' />
</svg> 




#4 楼

您可以使用径向渐变真正轻松地做到这一点。
DEMO
结果:

HTML:
<div class='shape'></div>

相关CSS:
.shape {
  margin: 0 auto;
  width: 10em; height: 16em;
  /* WebKit browsers, old syntax */
  background: -webkit-radial-gradient(50% 0, circle, transparent 30%, black 30%);
  
  /* IE10, current versions of Firefox and Opera */
  background: radial-gradient(circle at 50% 0, transparent 30%, black 30%);
}

有关兼容性的详细信息,请参见http://caniuse.com/#feat=css-gradients。

#5 楼

凯尔·索诺卡斯(Kyle Sevenokas)做得很好。我从那开始。检出http://jsfiddle.net/FcaVX/1/

我基本上将白色div折叠成圆形,并给了白色边框。 OP问题讨论了构成形状的颜色元素;它的边界没事吧?

评论


好的方法,但是我仍然瘦OP希望形状透明,这种方法也无法看到形状下面的背景。

–凯尔
2011-12-14 11:44

#6 楼

我只需要在响应图像的底部设置圆角。我从@sandeep小提琴开始,并根据需要对其进行了改进:

            .rect
            {
                height: 85vh;
                    position: relative;
                background-color: red;
                width: 60vw;
            }

            .circle-helper{
                display: block;
                width: 100%;
                padding-bottom: 50%;
                bottom: 0;
                left: 0;
                overflow: hidden;
                position: absolute;
                background-color: transparent;

                    }
            .circle{
                display: block;
                width: 100%;
                padding-bottom: 100%;
                // height: 500px;
                bottom: 0;
                left: 0;
                overflow: hidden;
                position: absolute;
                background-color: transparent;
            }

            .circle:after{
                box-sizing: content-box;
                content: '';
                width: 100%;
                height: 100%;
                -moz-border-radius: 50%;
                -webkit-border-radius: 50%;
                border-radius: 50%;
                background: rgba(0,0,0,0);
                position: absolute;
                transform: translate(-50%, -50%);
                top: 50%;
                left: 50%;
                border: 300px solid blue;
                }
                top: 50%
                left: 50%
                border: 300px solid blue


https://jsfiddle.net/mop00j22/

#7 楼

试试这个。




 body{
  
  background-color:#333;
  passing:0px;
  height:0px;
  
}
#app{
  background:#333 url('https://source.unsplash.com/random') no-repeat;
  background-size:cover;
  width:360px;
  height:560px;
  position:relative;
  overflow:hidden;
}
.app-bar{
  width:100%;
  height:50px;
  position:absolute;
  bottom:0px;
  left:0;
  
  
    
}

.app-bar .bar{
  line-height:50px;
  
  position:relative;
  width:100%;
  height:50px;
  background-image: radial-gradient(circle 35px at 315px 0, transparent 700px, #f44336 50px);
    
}


.app-bar .bar i{
  color:#FFF;
  display:block;
  line-height:50px;
  float:left;
  width:50px;
  text-align:center;
  cursor:pointer;
  margin-top:0px;
}
.app-bar .bar i:hover{
  background-color:rgba(0,0,0,.1);
}
.app-bar .bar button{
  padding:0px;
  box-sizing:border;
  text-align:center;
  margin:0px;
  bordeR:0px;
  outline:0px;
  width:60px;
  height:60px;
  line-height:60px;
  cursor:pointer;
  color:#FFFFFF;
  display:block;
  border-radius:50%;
  position:absolute;
  top:-30px;
  left:100%;
  margin-left:-75px;
  background-color:#f44336;
  transition: all .2s ease;
  
}
.app-bar .bar button span{
  line-height:60px;
  font-size:30px;
  
}
.app-bar .bar button:hover{
  transform:rotate(45deg);
  transition: all .2s ease;
} 

 <div id="app">
  <div class="app-bar">
    
    <div class="bar">
      <i class="material-icons">menu</i>
      <i class="material-icons">search</i>
      <button class="button">
        <span class="material-icons">add</span>
      </button>
    </div>
  </div>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.1/iconfont/material-icons.min.css" > 




#8 楼

现在,我能想到的唯一方法是在彼此相邻的高度上使用许多1像素宽的黑色div。从技术上讲,这种方式是可行的,但应该对此深表歉意。也;除非您想解决添加1x1像素div并手动进行抗锯齿的麻烦,否则您将不会使用抗锯齿。

如果您举一个例子说明您可能会有所帮助想用这个。为什么只需要黑色/透明?正如omarello所说,在大多数情况下,最好的解决方案可能是具有透明度的简单GIF或PNG图像。