透明的空心或切出的圆圈
Posted
技术标签:
【中文标题】透明的空心或切出的圆圈【英文标题】:Transparent hollow or cut out circle 【发布时间】:2012-01-07 08:43:33 【问题描述】:是否可以仅使用 CSS切出一个空心圆?
这是我们都可以做到的:
但是我们可以这样做吗?
圆圈必须是空心透明的。因此,通过在div
上放置一个纯色圆圈并不能解决问题。
【问题讨论】:
通过'only CSS'大概你更喜欢不使用图片/image-masks? 我想这样做,但使用带有背景图像的元素,而不仅仅是纯色。这可能吗? 【参考方案1】:您可以使用 2 种不同的技术实现透明切割圆:
1.SVG
以下示例使用inline svg。第一个 sn-p 使用mask element 切出透明圆,第二个空心圆使用path element。圆圈由 2 arc commands 组成:
带遮罩元素:
bodybackground:url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;
<svg viewbox="0 0 100 50" >
<defs>
<mask id="mask" x="0" y="0" >
<rect x="5" y="5" fill="#fff"/>
<circle cx="50" cy="25" r="15" />
</mask>
</defs>
<rect x="0" y="0" mask="url(#mask)" fill-opacity="0.7"/>
</svg>
只有一个路径元素:
bodybackground: 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。 CSS 仅使用 BOX-SHADOWS
使用overflow:hidden;
创建一个div,并在其中创建一个带有border-radius 的圆形伪元素。给它一个巨大的盒子阴影并且没有背景:
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;
bodybackground: url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-size:cover;
<div></div>
对 box-shadows 的浏览器支持是 IE9+,请参阅 canIuse
同样的方法是使用边框而不是框阴影。如果您需要支持不支持像 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>
【讨论】:
非常感谢你的 box-shadow,天哪,我怎么没想到那个! :/我知道可以使用一些超出边界的圆圈来完成。但你成功了! 注意如果在 Safari 中使用 box-shadow .. 它们是不可见的,但边框是可见的。请改用它们。【参考方案2】:可以使用radial gradient 背景和指针事件来完成(允许鼠标通过圆圈层进行交互,例如文本选择)。这是a demo page 和截图:
这就是它的代码:
<!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 不客气。如果您对矩形穿透窗口感兴趣,我前段时间发布了类似的答案:***.com/questions/7979675/… 然而,这给出了一个边缘非常“粗糙”的圆,所以如果有人有一个解决方案可以产生一个很好渲染的穿透圆,那么它是非常受欢迎的。 @chris 如果圆圈的大小是固定的,则使用居中的背景图像,但保留pointer-events
部分。如果大小不同,那么您可以使用 SVG 为 WebKit developer.mozilla.org/en/CSS/-webkit-mask 和 Firefox developer.mozilla.org/En/Applying_SVG_effects_to_HTML_content 创建掩码
@BenRacicot 小提琴没有坏。在此处查看复制粘贴:output.jsbin.com/wibiyawawi
@IonuțG.Stan,谢谢你的回答。但它可以与图像结合吗?所以不是黑色而是被图像掩盖?【参考方案3】:
参考 web-tiki 的回答,我想补充一点,您始终可以使用 translate(-50%,-50%)
将 div 居中,因此使用 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;
bodybackground: 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>
【讨论】:
对于像我这样挣扎的人 - div:after 需要 box-sizing: content-box;有时由 css 框架设置为边框。【参考方案4】:关于“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>
【讨论】:
【参考方案5】:方法1- 首选
<div class="circle"></div>
$radius: 50px;
$thickness: 5px;
.circle
width: $radius;
height: $radius;
background-color: transparent;
border-radius: $radius;
border: $thickness solid gray;
方法二
<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不只是创建一个边框吗?圆圈外的整个区域都应该涂上颜色。不仅仅是边界。【参考方案6】:您可以使用 css 蒙版和额外的 svg 图片来做到这一点。Although browser support is weak
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>
【讨论】:
【参考方案7】:我们可以使用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>
【讨论】:
以上是关于透明的空心或切出的圆圈的主要内容,如果未能解决你的问题,请参考以下文章