【问题标题】:Transparent half circle cut out of a div从 div 中切出的透明半圆
【发布时间】:2012-01-20 04:15:51
【问题描述】:

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

不能使用上面有一个白色圆圈的黑色矩形,因为半个圆圈必须是透明的并让背景透过。

想要的形状:

【问题讨论】:

  • 这是一个“做我的家庭作业”的问题吗???嗯
  • 为什么不想用白圈?
  • 只需将上图用作background-image!从技术上讲,它只是 css3
  • 我不想使用白色圆圈,因为我希望形状是透明的。

标签: html css css-shapes


【解决方案1】:

Kyle Sevenokas 做得很好。我以此为基础。查看http://jsfiddle.net/FcaVX/1/

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

【讨论】:

  • 好方法,但我还是瘦了OP希望形状透明,这种方法也无法看到形状下方的背景。
【解决方案2】:

也许可以用 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"> <span class="circle"></span></div>

View on JSFiddle

【讨论】:

  • 这很好。我有点困惑它是如何工作的,但是从.circle 中删除overflow: hidden 后就很清楚了:jsfiddle.net/thirtydot/FcaVX/3
  • 近乎完美。现在只需将所有rgba(0,0,0,0.5) 颜色更改为#000。瞧!好好运动,OP,好好运动
【解决方案3】:

现在,我能想到的唯一方法是使用大量 1 像素宽的黑色 div,它们彼此相邻且高度不同。这种方式在技术上是可行的,但应该对此深表反对。还;除非您想解决添加 1x1 像素 div 并手动进行抗锯齿的麻烦,否则您不会有抗锯齿。

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

【讨论】:

    【解决方案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】:

    您可以使用 box-shadows 来制作透明切出的圆形

    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;
    }
    &lt;div class="transparent"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案6】:

      使用 SVG:

      这是使用 SVG 的替代解决方案(尽管您没有标记它)。使用 SVG 的优点是:

      • 与径向渐变相比,它具有更好的浏览器支持。
      • 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 规范,我们可以试试下面的sn-p。

      .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,它只会产生一个椭圆(如 sn-p 所示)。为了克服这个问题,我们必须将剪切路径放在子元素(或伪元素)上,这意味着剪切区域不会是透明的


      使用画布:

      同样可以使用 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>

      【讨论】:

        【解决方案7】:

        我只需要在响应式图片的底部使用圆角。我从@sandeep fiddle 开始,并根据我的需要对其进行了改进:

                    .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/

        【讨论】:

          【解决方案8】:

          试试这个。

          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" >

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-20
            • 1970-01-01
            • 2021-01-14
            • 2012-01-07
            • 2016-12-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多