透明的空心或切出的圆圈


71

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

我们都可以做到:

普通CSS圈

但是,我们可以这样做吗?

div中的透明空心圆

圆必须是空心且透明的。因此,不能通过将纯色圆圈放在上来解决问题div


1
通过“仅CSS”,您大概不想使用图像/图像蒙版
大卫说,请恢复莫妮卡(Monica)

我想这样做,但是要使用具有背景图像的元素,而不仅仅是纯色。那可能吗?
Toskan

Answers:


80

您可以使用2种不同的方法来实现透明的切出圆

1.SVG

以下示例使用内联svg。第一个片段使用mask元素切出透明圆圈,第二个空心圆圈由path元素制成。该圆是通过2条圆弧命令制成的:

使用mask元素:

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>

具有一个路径元素:

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>

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

  • 较短的代码
  • 您可以轻松地使用图像或渐变色来填充圆形蒙版
  • 保持形状的边界并仅在相对于蒙版的填充上触发鼠标(在示例中将鼠标悬停在透明的切出圆圈上)

透明切出的圆圈

2.仅使用BOX-SHADOWS的CSS

创建一个div,overflow:hidden;并在其中创建一个带有border-radius的圆形伪元素。给它一个巨大的阴影,没有背景:

IE9 +的浏览器对盒子阴影的支持请参见canIuse

相同的方法是使用边框而不是框阴影。有趣的是,如果您需要支持不支持IE8等框阴影的浏览器。技巧相同,但是您需要补偿顶部和左侧的值,以将圆保持在div的中心:


1
非常感谢您提供盒装阴影,哦,天哪,我为什么没有想到那个!:/我知道可以使用越界的圆来完成。但是你钉了它!
丹麦

注意,如果在Safari ..中使用框阴影,则它们不可见,但有边框。改用它们。
Stefan Rein

26

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

在此处输入图片说明

这就是它的代码:

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

@chris不客气。如果你有兴趣在一个矩形穿通的窗口,我已经张贴了类似的答案前一阵子:stackoverflow.com/questions/7979675/...
约努茨G.斯坦

但是,这会产生一个带有非常“粗糙”边缘的圆,因此,如果有人有解决方案可以产生清晰渲染的穿通圆,则非常欢迎。
克里斯,

@chris如果圆的大小是固定的,则使用居中的背景图像,但保留该pointer-events部分。如果大小不同,则可以在SVG中为WebKit developer.mozilla.org/en/CSS/-webkit-mask和Firefox developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content
Ionuț G. Stan,

@BenRacicot小提琴没有坏。看到复制粘贴在这里:output.jsbin.com/wibiyawawi
Praveen Kumar Purushothaman

@ IonuțG.Stan,谢谢您的回答。但是,它可以与图像结合吗?因此,它会被图像遮盖而不是黑色?
阿纳托利

15

关于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>

您可以使用此技术真正发挥创意:

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>


1
对于那些像我这样挣扎的人-div:after需要调整大小:content-box; CSS框架有时会将其设置为border-box。
Branislav Kuliha'2

6

关于“ Pius Nyakoojo”中的“方法1”,只要稍作改进(请参见下文),它就可以工作。我个人认为这是最简单的解决方案:

屏幕截图

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

1

方法1-首选

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

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

方法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;
}

方法1不只是创建边框吗?圆圈外的整个区域都应着色。不只是边界。
克里斯(Chris

0

您可以使用CSS蒙版和额外的SVG图片进行操作。
尽管浏览器支持薄弱

![在此处输入图片描述

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>


0

我们可以使用radial-gradient和来做到这一点mask。使用单个div时,没有伪元素。

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background-image: url(https://picsum.photos/id/1060/720/1280);
  background-size: cover;
}

.a {
  /* this is flexible. you can change */
  --circle-radius: 100px;
  height: 100%;
  width: 100%;
  --mask: radial-gradient(circle farthest-side at center center, transparent var(--circle-radius), #000 calc(var(--circle-radius) + 2px) 100%) 50% 50%/100% 100% no-repeat;
  -webkit-mask: var(--mask);
          mask: var(--mask);
  background: #000;
}
<div class="a"></div>

圆半径也可以是百分比值:

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  padding: 30px;
  background-image: url(https://picsum.photos/id/1060/720/1280);
  background-size: cover;
}

.a {
  --circle-radius: 20%; /* changed as percent value */
  
  height: 100%;
  width: 100%;
  --mask: radial-gradient(circle farthest-side at center center, transparent var(--circle-radius), #000 calc(var(--circle-radius) + 2px) 100%) 50% 50%/100% 100% no-repeat;
  -webkit-mask: var(--mask);
          mask: var(--mask);
  background: rgba(0, 0, 0, .8);
}
<div class="a"></div>

另一个想法:

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background-image: url(https://picsum.photos/id/1060/720/1280);
  background-size: cover;
}

.a {
  --circle-radius: 100px;
  --border-width: 30px;
  
  height: 100%;
  width: 100%;
  --mask: radial-gradient(circle farthest-side at center center, transparent var(--circle-radius), #000 calc(var(--circle-radius) + 2px) calc(var(--circle-radius) + 2px + var(--border-width)), transparent calc(var(--circle-radius) + 2px + var(--border-width) + 2px) 100%) 50% 50%/100% 100% no-repeat;
  -webkit-mask: var(--mask);
          mask: var(--mask);
  background: #000;
}
<div class="a"></div>

逆转:

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background-image: url(https://picsum.photos/id/1060/720/1280);
  background-size: cover;
}

.a {
  --circle-radius: 100px;
  --border-width: 30px;
  
  height: 100%;
  width: 100%;
  --mask: radial-gradient(circle farthest-side at center center, #000 var(--circle-radius), transparent calc(var(--circle-radius) + 2px) calc(var(--circle-radius) + 2px + var(--border-width)), #000 calc(var(--circle-radius) + 2px + var(--border-width) + 2px) 100%) 50% 50%/100% 100% no-repeat;
  -webkit-mask: var(--mask);
          mask: var(--mask);
  background: #000;
}
<div class="a"></div>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.