CSS 透明空心或切出的圆形

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8286550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 02:14:31  来源:igfitidea点击:

Transparent hollow or cut out circle

csssvgtransparencycss-shapes

提问by Chris

Is it possible to cut out a hollow circleusing only CSS?

是否可以仅使用CSS切出一个空心圆

This we can all do:

这是我们都可以做到的:

normal CSS circle

normal CSS circle

But can we do this?

但是我们能做到吗?

transparent hollow circle in a div

transparent hollow circle in a div

The circle must be hollow and transparent. Thus the problem is not solved by putting a solid color circle over a div.

圆必须是中空的,并且透明。因此,通过在 a 上放置一个纯色圆圈不能解决问题div

回答by web-tiki

You can achieve a transparent cut out circlewith 2 different techniques :

您可以使用 2 种不同的技术实现透明的切出圆

1.SVG

1.SVG

The following examples use an inline svg. The first snippet uses the mask elementto cut out the transparent circle and the second hollow circle is made with a path element. The circle is made with 2 arc commands:

以下示例使用内联 svg。第一个片段使用mask 元素切出透明圆,第二个空心圆由path 元素制成。圆由 2 个圆弧命令构成

With the mask element :

使用掩码元素:

body{background:url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;}
<svg viewbox="0 0 100 50" width="100%">
  <defs>
    <mask id="mask" x="0" y="0" width="80" height="30">
      <rect x="5" y="5" width="90" height="40" fill="#fff"/>
      <circle cx="50" cy="25" r="15" />
    </mask>
  </defs>
  <rect x="0" y="0" width="100" height="50" mask="url(#mask)" fill-opacity="0.7"/>    
</svg>

With one path element :

使用一个路径元素:

body{background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;}
svg{
  display:block;
  width:70%;
  height:auto;
  margin:0 auto;
}
path{
  transition:fill .5s;
  fill:#E3DFD2;
}
path:hover{
  fill:pink;
}
<svg viewbox="-10 -1 30 12">
  <path d="M-10 -1 H30 V12 H-10z M 5 5 m -5, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0z"/>
</svg>

The main advantages of using SVG in this case are :

在这种情况下使用 SVG 的主要优点是:

  • Shorter code
  • You can easily use an image or gradient to fill the circle mask
  • maintain the boundaries of the shape and trigger mouse envents only over the fill respecting the mask (hover the transparent cut out circlein the example)
  • 较短的代码
  • 您可以轻松地使用图像或渐变来填充圆形蒙版
  • 保持形状的边界并仅在关于蒙版的填充上触发鼠标事件(在示例中悬停透明切出的圆圈

transparent cut out circle

transparent cut out circle

2. CSS only using BOX-SHADOWS

2. CSS 只使用 BOX-SHADOWS

Create a div with overflow:hidden;and a round pseudo element inside it with border-radius. Give it a huge box-shadow and no background :

在其中创建一个overflow:hidden;带有边界半径的圆形伪元素的 div 。给它一个巨大的盒子阴影,没有背景:

div{
    position:relative;
    width:500px; height:200px;
    margin:0 auto;
    overflow:hidden;
}
div:after{
    content:'';
    position:absolute;
    left:175px; top:25px;
    border-radius:100%;
    width:150px; height:150px;
    box-shadow: 0px 0px 0px 2000px #E3DFD2;
}

body{background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;}
<div></div>

Browser support for box-shadows is IE9+ see canIuse

浏览器对 box-shadows 的支持是 IE9+ 查看canIuse

The same approach would be to use border instead of box-shadows. It is interesting if you need to support borowsers that don't support box-shadows like IE8. The technique is the same but you need to compensate with the top and left values to keep the circle in the center of the div :

同样的方法是使用边框而不是框阴影。如果你需要支持不支持像 IE8 这样的 box-shadows 的浏览器,这很有趣。该技术是相同的,但您需要使用 top 和 left 值进行补偿以将圆保持在 div 的中心:

body{
    background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');
    background-size:cover;
}
div{
    position:relative;
    width:500px; height:200px;
    margin:0 auto;
    overflow:hidden;
}
div:after{
    content:'';
    position:absolute;
    left:-325px; top:-475px;
    border-radius:100%;
    width:150px; height:150px;
    border:500px solid #E3DFD2;
}
<div></div>

回答by Ionu? G. Stan

It can be done using a radial gradientbackground and pointer-events (to allow mouse interaction behind through the circle layer, e.g. text selection). Here's a demo pageand a screenshot:

它可以使用径向渐变背景和指针事件来完成(允许鼠标通过圆形层进行交互,例如文本选择)。这是一个演示页面和屏幕截图:

enter image description here

enter image description here

And this would be the code for it:

这将是它的代码:

<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8">
<style type="text/css" media="screen">
body {
  margin: 0;
  padding: 0;
}

.underneath {
  padding: 0;
  margin: 265px 0 0 0;
  width: 600px;
}

.overlay {
  top: 0;
  left: 0;
  position: absolute;
  width: 600px;
  height: 600px;
  background: -moz-radial-gradient(transparent 150px, rgba(0,0,0,1) 150px);
  background: -webkit-radial-gradient(transparent 150px, rgba(0,0,0,1) 150px);
  background: -ms-radial-gradient(transparent 150px, rgba(0,0,0,1) 150px);
  background: -o-radial-gradient(transparent 150px, rgba(0,0,0,1) 150px);
  pointer-events: none; /* send mouse events beneath this layer */
}
</style>
</head>
<body>

<p class="underneath">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
  incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
  nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
  eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
  in culpa qui officia deserunt mollit anim id est laborum.
</p>

<div class="overlay"></div>

</body>
</html>

回答by doABarrelRoll721

Referring to web-tiki's answer I'd like to add that you can always center a div with translate(-50%,-50%), so it'd be no problem to use the border-property, which has better browser support.

参考 web-tiki 的答案,我想补充一点,您始终可以使用 将 div 居中translate(-50%,-50%),因此使用border具有更好浏览器支持的-property没有问题。

div{
    position:relative;
    width:500px; 
    height:200px;
    margin:0 auto;
    overflow:hidden;
}
div:after{
    content:'';
    position:absolute;
    left:50%;
    top: 50%;
    transform: translate(-50%,-50%);
    border-radius:50%;
    width:150px; height:150px;
    border: 1000px solid rebeccapurple;
}

body{background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;}
<div></div>

You can get really creative with this technique:

您可以通过这种技术获得真正的创意:

document.addEventListener( "DOMContentLoaded", function(){ 
 setInterval(function(){
  if(document.getElementById("moving").style.height === "500px"){
   document.getElementById("moving").style.height = "0px";
  } else {  
   document.getElementById("moving").style.height = "500px";
  }
 }, 2000);
});
#container {
 width: 500px;
 margin: 0 auto;
 border: 1px solid black;
 overflow:hidden;
 position: relative;
}


#circle{
    position:relative;
    height:150px;
    margin:0 auto;
 clear:left;
 overflow:hidden;
}
#circle::before, #circle::after {
    content:'';
    border-radius:50%;
 position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}
#circle::before {
    height: 140px;
    width: 140px;
    background: rebeccapurple;
}
#circle::after{
    width:150px; 
 height:150px;
    border: 2000px solid rebeccapurple;
}

#line {
 margin: 0 auto;
 width: 6px;
 height: 200px;
 position: relative;
}
#line::before, #line::after {
 content: " ";
 background-color: rebeccapurple;
    height: 200px;
 width:2000px;
 position:absolute;
}
#line::before {
 right: 100%;
}
#line::after { 
 left: 100%;
}

#moving {
 height: 0px;
    width: 100%;
    background: blue;
    transition: 2s height;
    position: absolute;
    top: 0px;
    z-index: -1;
}
body{
 background: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;
}
<div id="container">
 <div id="circle"></div>
 <div id="line"></div> 
    <div id="circle"></div>
    <div id="moving"></div>
</div>

回答by Andrew Tang

Regarding "Method 1" from "Pius Nyakoojo", with a minor improvement (see below) it would work. I personally think this is the simplest solution:

关于“Pius Nyakoojo”中的“方法 1”,稍加改进(见下文)即可。我个人认为这是最简单的解决方案:

screenshot

screenshot

<html>
<!-- Assuming the stuff to mask is a 100 pixel square -->
<style>
.mask {
    position: absolute;
    top: -50px;                     /* minus half the div size */
    left: -50px;                    /* minus half the div size */
    width: 100px;                   /* the div size */
    height: 100px;                  /* the div size */
    background-color: transparent;
    border-radius: 100px;           /* the div size */
    border: 50px solid white;       /* half the div size */
    pointer-events: none;           /* send mouse events beneath this layer */
}

.stuff {
    position: absolute;
    width: 100px;                   /* the div size */
    height: 100px;                  /* the div size */
    overflow: hidden;               /* hide the excess of the mask border */
    background-color: #CCC;
}
</style>
<body>
    <div class="stuff">
        <div class="mask"></div>
        blah blah blah blah blah
        blah blah blah blah blah
        blah blah blah blah blah
    </div>
</body>
</html>

回答by Pius Nyakoojo

Method 1- Preferred

方法 1-首选

<div class="circle"></div>
$radius: 50px;
$thickness: 5px;

.circle {
    width: $radius;
    height: $radius;
    background-color: transparent;
    border-radius: $radius;
    border: $thickness solid gray;
}

Method 2

方法二

<div class="circle"></div>
$radius: 50px;
$thickness: 5px;

.circle {
  width: $radius;
  height: $radius;
}

.circle::before, .circle::after {
  margin: -2px 0;
}
.circle::before {
    content: '';
    display: inline-block;
    width: $radius;
    height: calc(#{$radius} / 2);
    background-color: transparent;
    border-top-left-radius: calc(#{$radius} / 2);
    border-top-right-radius: calc(#{$radius} / 2);
    border: $thickness solid gray;
    border-bottom: 0;

    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

.circle::after {
  content: '';
  display: inline-block;
  width: $radius;
  height: calc(#{$radius} / 2);
  background-color: transparent;
  border-bottom-left-radius: calc(#{$radius} / 2);
  border-bottom-right-radius: calc(#{$radius} / 2);
  border: $thickness solid gray;
  border-top: 0;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

回答by Denis

You can do it using css masks and extra svg image.
Although browser support is weak

您可以使用 css 掩码和额外的 svg 图像来完成。
虽然浏览器支持较弱

![enter image description here

![enter image description here

body {
  background: url(https://data.whicdn.com/images/50959200/original.jpg);
  background-size: cover;
  background-position: center;
}

.circle {
  width: 150px;
  height: 150px;
  background: black;
  border-radius: 50%;
  -webkit-mask: url(https://svgshare.com/i/GLf.svg);
  -webkit-mask-size: 125%; /* change it */
  -webkit-mask-position: center;
  margin: 20px auto;
}
<div class="circle"></div>