是否可以使用CSS创建此形状(两个部分圆连接在一起)?

Joe*_*ano 42 html css html5 css3 css-shapes

我试图用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;
 }
Run Code Online (Sandbox Code Playgroud)
<div class="left"></div>
<div class="right"></div>
Run Code Online (Sandbox Code Playgroud)

我可以进一步将它们压在一起,但我必须让另一个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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="left"></div>
<div class="right"></div>
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何在没有div重叠的情况下实现这一目标?

Ste*_*ide 45

SVG

使用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>
Run Code Online (Sandbox Code Playgroud)

SVG代表可伸缩矢量图形.Web浏览器将其视为图像,但您可以在SVG中添加文本和普通HTML元素.

所有浏览器都支持它,如下所示:CanIUse


Har*_*rry 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; }
Run Code Online (Sandbox Code Playgroud)
<div class='left'></div>
<div class='right'></div>
Run Code Online (Sandbox Code Playgroud)


使用径向渐变:

如果你不想overflow: hidden在父元素上使用伪元素和a元素,那么你也可以利用radial-gradient背景图像来产生圆形并定位它们,使它们最终产生所需的效果.以下是此方法的示例代码段.

这种方法的缺点是浏览器支持率低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));
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='left'></div>
<div class='right'></div>
Run Code Online (Sandbox Code Playgroud)


使用剪辑路径(CSS/SVG):

可以使用的另一种方法是使用clip-path.这种方法的优点是hover只有当光标在圆圈内时才会触发效果(如代码片段所示).这是因为剪切了不必要的部分.

下行也是浏览器支持不佳的原因.clip-path仅在Webkit中支持CSS版本,但在Firefox,IE中不支持CSS版本,而在Webkit,Firefox但不支持IE中支持SVG版本(使用内联SVG).

.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; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Rou*_*ica 12

这是一个只使用一个解决方案的解决方案<div>.

  1. .shape是一个带10px红色边框的透明圆圈.
  2. .shape::before是一个带有10px红色边框的不透明白色圆圈.
  3. .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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="shape">
</div>
Run Code Online (Sandbox Code Playgroud)

  • @Harry哦,不.我只是比较了仅支持SVG的解决方案.此外,这略微优于其他答案,因为它减少了空元素的数量.有些人对空标签非常严格.但这也适用于`<span>`.没有人抱怨空的"<span>",对吧? (2认同)

小智 8

这是我想出的一个简单例子.我没有在不同的浏览器中测试它,但它应该得到相当好的支持.

HTML:

<div class="one"></div>
<div class="two"></div>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示