Transparent half circle cut out of a div

前端 未结 8 2439
一生所求
一生所求 2020-11-22 05:34

I would like to make a transparent cut out half circle shape using only CSS3. The only requirement is that all the elements that form the shape must

8条回答
  •  醉梦人生
    2020-11-22 05:53

    Using SVG:

    Here is an alternate solution using SVG (though you haven't tagged it). Advantages of using SVG are:

    • It has better browser support when compared to radial-gradients.
    • SVG can support images inside the shape unlike the box-shadow approach.

    While SVG is not supported by <= IE8 whereas box-shadow is, fallbacks can be provided.

    svg {
      height: 150px;
      width: 150px;
    }
    polygon {
      fill: black;
    }
    
    /* Just for demo */
    
    body {
      background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
    }
    
    
      
        
          
        
      
      
    
    
    
    
      
        
      
      
    


    Using CSS:

    CSS also has clip-path specifications and we can try something like in the below snippet.

    .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;
    }

    But unlike SVG clip-path, the pure CSS version (that is, without using an inline or external SVG) doesn't seem to be able to support a path. It only supports shapes and so in this case, if you use the clip-path on the parent directly it would just produce an ellipse (like shown in the snippet). To overcome this, we would have to put the clip-path on a child (or a pseudo element) and this would mean that the clipped area would not be transparent.


    Using Canvas:

    The same can be done using Canvas also. Canvas commands are pretty similar to SVG and their advantages are also pretty similar. However, Canvas are raster based and hence doesn't scale as well as SVG does.

    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%);
    }
    
    


    Using Masks:

    This shape can be created by using CSS (or) SVG masks also. CSS masks have very poor support and work currently only in Webkit powered browsers but SVG masks have much better support and should work in 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%);
    }
    
    
    

提交回复
热议问题