【翻译】4种CSS画圆的方法

四种方法

1. Border Radius

.circle {
  background: #456BD9;
  border: 0.1875em solid #0F1C3F;
  border-radius: 50%;
  box-shadow: 0.375em 0.375em 0 0 rgba(15, 28, 63, 0.125);
  height: 5em;
  width: 5em;
}

将border-radius设为50%是最常见、支持最广泛的方法。border-radius属性同时会影响边框、阴影,以及元素的点击面积

2. SVG

<svg viewBox="0 0 80 80" width="80" height="80">
  <circle class="circle" cx="40" cy="40" r="38"/>
</svg>

SVG有circle元素,可以实现圆形。SVG的支持也很广泛,而且用作动画性能很好,但代码量略大。要注意,为了防止圆形视觉上被遮罩,确保圆的半径(如果有笔画宽度,也要加上)比SVG的viewBox略小一点。

3. Clip Path

.circle {
  background: #456BD9;
  clip-path: circle(50%);
  height: 5em;
  width: 5em;
}

Clip path是新的技术。支持也很广但一致性不足。Clip Path不会影响元素的布局,也就是说它不会影响边框,同时会隐藏outer shadow。取决于你所要达到的效果,这可能是有用的。

4. Radial Gradient

.circle {
  background-image: radial-gradient(circle, #456BD9, #456BD9 66%, transparent 66%);
  height: 5em;
  width: 5em;
}

我们可以用background-image和radial-gradient来视觉上用圆形填充一个元素。任何内容可以在这个圆形之上,但它的布局(包括可点击面积)不会被影响。这是我最不喜欢的方式,因为不同浏览器下,圆的边缘可能看上去会模糊、锯齿。但它不失为是一个为背景增色的不错办法。

居中内容

任何用来居中元素的CSS方法都可以使用。但有的时候,你会发现内容没有完全的居中。这在元素变小时尤为明显。这种情况不只出现在圆形元素中。

【翻译】4种CSS画圆的方法

对应代码@codepen

这个问题源于浏览器计算sub-pixel的方法。我们用相对单位、viewport单位或em单位的时候,浏览器可能会计算出非整数的数值。过去,这个问题可能会妨碍栅格布局或者导致其它的问题。现在,浏览器会针对不同的元素、属性、上下文优化计算结果,但仍有不完美。

我的经验是,最灵活的办法就是使用绝对定位来建立一个中心点,然后transform(将子元素移至中心点)

<div class="circle">
  <svg class="circle-icon" viewBox="0 0 24 24" width="24" height="24">
    <line x1="2" x2="22" y1="5"  y2="5"  stroke-width="3" stroke-linecap="round"/>
    <line x1="2" x2="22" y1="12" y2="12" stroke-width="3" stroke-linecap="round"/>
    <line x1="2" x2="22" y1="19" y2="19" stroke-width="3" stroke-linecap="round"/>
  </svg>
</div>
.circle-icon {
  fill: currentColor;
  height: 50%;
  left: 50%;
  position: absolute;
  stroke: currentColor;
  stroke-width: 0;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 50%;
}

剪裁内容

用图片填充一个圆形。

用HTML/CSS

我们可以用border-radius来裁剪一个<img>元素。

.circle {
  background: rgba(15, 28, 63, 0.125);
  border-radius: 50%;
  height: 8em;
  object-fit: cover;
  width: 8em;
}

局限性:

  1.  这个元素对于它的容器不是响应式的
  2. 我们无法应用inner shadow来让这个图片从背景中偏移
  3. 我们使用object-fit来防止非正方形图片的变形,但这在IE11中未得到支持。

这是一个更精致的例子,解决了以上问题。

使用SVG

使用svg也可以达到相同的效果。但要注意svg的image元素不支持srcset或sizes。

<svg viewBox="0 0 100 100" width="100" height="100">
  <title>Tyler</title>
  <defs>
    <circle id="circle" cx="50" cy="50" r="49" vector-effect="non-scaling-stroke"/>
    <clipPath id="circle-clip">
      <use xlink:href="#circle"/>
    </clipPath>
  </defs>
  <g clip-path="url(#circle-clip)">
    <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62127/penguin.jpg" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"/>
    <use xlink:href="#circle" fill="none" stroke="#0F1C3F" stroke-width="2" opacity="0.25"/>
  </g>
</svg>

Sub-pixel 间隙

如果你在圆形元素上增加阴影、边框等属性,可能会注意到一些半像素的缺陷问题。

【翻译】4种CSS画圆的方法

这个暂时还没有解决方案。

文字环绕

使用shape-outside属性,可以使文字圆形环绕。(注意圆形周围的margin)

【翻译】4种CSS画圆的方法

 内部填充文字

未来w3c可能会有shape-inside属性。目前通过一个hack,可以实现。

【翻译】4种CSS画圆的方法

但这个方法不是响应式的。通过padding可以达到一个类似的响应式结果。

【翻译】4种CSS画圆的方法

文字沿着圆周

可以通过SVG和<textPath>元素,让文字沿着圆周。

<svg viewBox="0 0 100 100" width="100" height="100">
  <defs>
    <path id="circle"
      d="
        M 50, 50
        m -37, 0
        a 37,37 0 1,1 74,0
        a 37,37 0 1,1 -74,0"/>
  </defs>
  <text font-size="17">
    <textPath xlink:href="#circle">
      You spin me right round, baby...
    </textPath>
  </text>
</svg>

并不是所有的浏览器都支持<circle>的<textPath>,但将circle转换为path并不难。

来源:https://cloudfour.com/thinks/css-circles/

css

相关推荐