四種方法
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方法都可以使用。但有的時候,你會發現內容沒有完全的居中。這在元素變小時尤為明顯。這種情況不只出現在圓形元素中。
對應代碼@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; }
局限性:
- 這個元素對於它的容器不是響應式的
- 我們無法應用inner shadow來讓這個圖片從背景中偏移
- 我們使用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 間隙
如果你在圓形元素上增加陰影、邊框等屬性,可能會注意到一些半像素的缺陷問題。
這個暫時還沒有解決方案。
文字環繞
使用shape-outside屬性,可以使文字圓形環繞。(注意圓形周圍的margin)
內部填充文字
未來w3c可能會有shape-inside屬性。目前通過一個hack,可以實現。
但這個方法不是響應式的。通過padding可以達到一個類似的響應式結果。
文字沿着圓周
可以通過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並不難。