我试图用CSS完成两个div的边框:
我尝试使用border-radius
,但两个部分圈子没有按在一起:http://jsfiddle.net/uwz6L79w/
.left {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
border-width: 4px;
border-color: black white black black;
border-style: solid;
border-radius: 60px
}
.right {
position: absolute;
left: 104px;
top: 0;
width: 100px;
height: 100px;
border-width: 4px;
border-color: black black black white;
border-style: solid;
border-radius: 60px;
}
<div class="left"></div>
<div class="right"></div>
我可以再将它们压在一起,但我必须让一个div与另一个重叠,如下所示:http://jsfiddle.net/uwz6L79w/1/。
.left {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
border-width: 4px;
border-color: black white black black;
border-style: solid;
border-radius: 60px
}
.right {
position: absolute;
left: 70px;
top: 0;
width: 100px;
height: 100px;
border-width: 4px;
border-color: black black black white;
border-style: solid;
border-radius: 60px;
background: #f2f2f2;
}
<div class="left"></div>
<div class="right"></div>
有没有人知道如何在没有div重叠的情况下实现这一目标?
答案 0 :(得分:45)
使用SVG也可以。
SVG版本非常短,因为它主要只需要一个Arc命令来控制它的形状,大小和位置。
<svg width="50%" viewbox="0 0 100 50">
<path d="M50,35
a20,20 0 1,0 0,-20
a20,20 0 1,0 0,20z"
fill="white"
stroke="black">
</path>
</svg>
SVG代表可伸缩矢量图形。 Web浏览器将其视为图像,但您可以在SVG中添加文本和普通HTML元素。
所有浏览器都支持它,如下所示:CanIUse
答案 1 :(得分:41)
使用边框: 推荐
您可以使用与第二个代码段相同的方式执行此操作,并使用下面代码段中的定位来避免两个div
元素重叠。这里的圆圈是由伪元素产生的,重叠的部分是用父母的overflow: hidden
剪掉的。
这里需要注意的是,任何悬停效果都应该添加到伪元素而不是父元素上。这是因为如果:hover
附加到父级,那么即使将鼠标悬停在圆圈之外也会触发它(因为父级仍然是正方形)。
在这个答案提供的所有三个解决方案中,这是一个拥有最佳浏览器支持并且甚至可以在IE8中工作的解决方案。因此,这是推荐的。
.left, .right {
position: relative;
float: left;
height: 200px;
width: 200px;
/* border: 1px solid; uncomment to see that they aren't overlapped */
overflow: hidden;
}
.left:after, .right:after {
position: absolute;
content: '';
height: calc(100% - 12px); /* 12px because of 6px border on either side */
width: calc(100% - 12px); /* 12px because of 6px border on either side */
border-radius: 50%;
border: 6px solid gray;
}
.left:after { right: -20px; }
.right:after { left: -20px; }
<div class='left'></div>
<div class='right'></div>
使用径向渐变:
如果您不想在父级上使用伪元素和overflow: hidden
,那么您还可以使用radial-gradient
背景图像来生成圆圈并定位它们以便它们最终产生所需的效果。以下是此方法的示例代码段。
这种方法的缺点是low browser support for radial-gradient
。它不适用于IE9及更低版本。此外,由径向渐变产生的圆圈通常是锯齿状(粗糙边缘),当我们修改颜色停止位置以使其更平滑时,它会使外观略微模糊。
.left, .right {
float: left;
height: 200px;
width: 200px;
/*border: 1px solid; uncomment to see that they aren't overlapped */
}
/* generally the below code should be enough to produce 6px thick circular border
.left {
background: radial-gradient(circle at 70% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));
}
.right {
background: radial-gradient(circle at 30% 50%, transparent calc(50% - 3px), gray calc(50% - 3px), gray calc(50% + 3px), transparent calc(50% + 3px));
}
*/
/* but it produces jagged edges and so we can change the color stops a bit like below
this produces smoother circles but the disadvantage is that they'd look a bit blurred */
.left {
background: radial-gradient(circle at 70% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));
}
.right {
background: radial-gradient(circle at 30% 50%, transparent calc(50% - 4px), gray calc(50% - 2px), gray calc(50% + 2px), transparent calc(50% + 4px));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='left'></div>
<div class='right'></div>
使用剪辑路径(CSS / SVG):
可以使用的另一种方法是使用clip-path
。这种方法的优点是只有当光标在圆圈内时才会触发hover
效果(如代码片段所示)。这是因为剪掉了不必要的部分。
下行又是poor browser support。仅在Webkit中支持clip-path
的CSS版本,但在Firefox,IE中不支持CSS版本,而在Webkit,Firefox中支持SVG版本(使用内联SVG),但不支持IE。
.left, .right {
float: left;
height: 200px;
width: 200px;
border-radius: 50%;
border: 6px solid gray;
}
/* CSS Clip Path - not supported by FF and IE */
.left.css-clip {
clip-path: polygon(0% 0%, 80% 0%, 80% 100%, 0% 100%);
}
.right.css-clip {
margin-left: -86px; /* 20% width * 2 (which is the clipped space) - border width */
clip-path: polygon(20% 0%, 100% 0%, 100% 100%, 20% 100%);
}
/* SVG Clip Path - supported by Webkit, FF but not IE */
.left.svg-clip {
clip-path: url(#clipper-left);
}
.right.svg-clip {
margin-left: -86px; /* 20% width * 2 (which is the clipped space) - border width */
clip-path: url(#clipper-right);
}
/* Just for demo */
h3{ clear: both; }
.left:hover, .right:hover{ background: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h3>CSS Clip Path</h3>
<div class='left css-clip'></div>
<div class='right css-clip'></div>
<h3>SVG Clip Path</h3>
<div class='left svg-clip'></div>
<div class='right svg-clip'></div>
<!-- Inline SVG for SVG Clip Path -->
<svg width='0' height='0'>
<defs>
<clipPath id='clipper-left' clipPathUnits='objectBoundingBox'>
<path d='M0,0 .8,0 .8,1 0,1z' />
</clipPath>
<clipPath id='clipper-right' clipPathUnits='objectBoundingBox'>
<path d='M.2,0 1,0 1,1 .2,1z' />
</clipPath>
</defs>
</svg>
答案 2 :(得分:12)
这是一个只使用一个<div>
的解决方案。
.shape
是一个带有10px
红色边框的透明圆圈。.shape::before
是一个不透明的白色圆圈,带有10px
红色边框。.shape::after
是一个不透明的白色圆圈(没有边框)。
.shape {
margin: 6px auto;
}
.shape, .shape::before, .shape::after {
display: block;
position: relative;
width: 160px;
height: 160px;
border-radius: 160px;
}
.shape, .shape::before {
border: 10px solid #f00;
}
.shape::before, .shape::after {
content: "";
background-color: rgba(255, 255, 255, 1);
}
.shape::before {
top: -10px;
left: -150px;
}
.shape::after {
top: -180px;
}
&#13;
<div class="shape">
</div>
&#13;
答案 3 :(得分:8)
这是我想出的一个简单例子。我没有在不同的浏览器中测试它,但它应该得到相当好的支持。
<强> HTML:强>
<div class="one"></div>
<div class="two"></div>
<强> CSS:强>
div {
background: #fff;
border-radius: 50%;
float: left;
height: 100px;
position: relative;
width: 100px;
}
.one:after,
.two:after{
/* adjust this to set the border color */
background: #666;
border-radius: 50%;
content: "";
position: absolute;
z-index: -1;
/* adjust these to set the border width */
top: -5px;
right: -5px;
bottom: -5px;
left: -5px;
}
.two {
/* adjust this to set the overlap of the circles */
margin-left: -20px;
}
答案 4 :(得分:2)
我回到这个问题(6周后),纯粹是因为最高投票的答案激起了我svg
的学术好奇心,我很少遇到这个问题而且从来没有花时间去学习。
因为我现在正在学习svg
,所以这个问题(这个问题让我最初想要学习它)似乎是尝试一些新技能的理想挑战。
所以这是一个替代 svg
解决方案,相当于我上面的单<div>
个css解决方案:
svg {
width: 310px;
height: 180px;
}
svg circle {
stroke: rgb(255,0,0);
stroke-width: 10;
fill: rgb(255,255,255);
}
svg circle:nth-of-type(3) {
stroke: rgb(255,255,255);
}
<svg viewbox="0 0 310 180">
<circle cx="90" cy="90" r="80" />
<circle cx="220" cy="90" r="80" />
<circle cx="90" cy="90" r="70" />
</svg>