用css能實現一個圓等分12份的樣子嗎?


我要是說不行,肯定會被打。可以看看下面的文章:

用CSS和SVG製作餅圖_CSS3, svg, CSS秘密花園 教程_w3cplus

基本解決方案就是介紹的,當然沒有像題主所說的12等份,但知道方案也就不難了。

這個方案從HTML的角度來說是最好的:它只需要一個元素,其它的都可以用偽元素、變換和CSS漸變完成。我們從下面這個簡單的元素開始:

&&

現在,假設我們希望顯示一個20%比例的餅圖。靈活性的問題我們後面再解決。我們先給元素添加樣式,讓它變成一個圓,也就是我們的背景:

第一步是先畫一個圓(或者可以說是顯示0%比例的餅圖)

.pie {
width: 100px; height: 100px;
border-radius: 50%;
background: yellowgreen;
}

我們的餅圖是綠色(特指yellowgreen)和棕色(#655)顯示的百分比。可能會在比例部分嘗試使用transform中的skew,但是經過幾次試驗之後表明,這是一個非常混亂的方案。因此,我們用這兩種顏色為這個餅圖的左右部分分別著色,然後對於我們想要的百分比,使用旋轉的偽元素來實現。

我們使用一個簡單的線性漸變,給右半部分著棕色:

background-image: linear-gradient(to right, transparent 50%, #655 0);

用一個簡單的線性漸變給右半圓著棕色

這樣就完成了。現在,我們可以繼續為偽元素添加樣式,讓它成為一個蒙版:

.pie::before {
content: "";
display: block;
margin-left: 50%;
height: 100%;
}

虛線內的內容表示偽元素將作為蒙版的區域

你可以在圖3中看到我們的偽元素當前定位相對於我們的pie元素。目前,它還沒有添加樣式,也沒有覆蓋任何東西,只是一個透明的矩形。在開始添加樣式之前,我們先來分析一下:

  • 因為我們希望它覆蓋圓的棕色部分,我們需要給它應用一個綠色的背景,使用background-color: inherit來避免重複定義,因為我們本來就希望它和父元素的背景顏色保持一致。
  • 我們希望它繞著圓的中心點旋轉,中心點在偽元素的左邊,所以我們需要給它的transform-origin,應用一個0 50%,或者是直接一個left。
  • 我們不想要它是一個矩形,因為它會超過餅圖的邊緣,所以我們需要給.pie應用overflow: hidden,或者是一個恰當的border-radius讓它成為一個半圓。

綜上所述,偽元素的CSS樣式如下:

.pie::before {
content: "";
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
}

添加樣式之後的偽元素(這裡用虛線表示)

注意:不要使用background: inherit;,要用background-color: inherit;,否則父元素背景圖像上的漸變也會被繼承

我們的餅圖目前如圖4所示。現在開始有趣起來了!我們可以開始旋轉偽元素,給它應用一個rotate()變換。要顯示20%的比例,我們可以給它一個72deg(0.2 x 360 = 72),或.2turn,這個可讀性更好。你可以在圖5中看到不同旋轉角度值的結果。

分別展示不同百分比的餅圖,從左到右:10% (36deg 或 .1turn), 20% (72deg 或 .2turn), 40% (144deg 或.4turn)

你可能會想我們已經完成了,但是它可沒這麼簡單。我們的餅圖在展示0到50%的大小的內容時是沒有任何問題的,但是如果我們要描繪一個60%的旋轉(通過應用.6turn),就會發生如圖6的情況。但是,別擔心,我們可以解決這個事情!

對於超過50%的比例,我們的餅圖就跪了orz(這裡的是60%)

如果我們把50%-100%比例的情況作為單獨的一個問題,可能會注意到可以使用之前的解決方案的反相版本:從0到.5turn旋轉的棕色偽元素。所以,對於一個60%的餅圖,偽元素的CSS代碼如下:

.pie::before {
content: "";
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background: #655;
transform-origin: left;
transform: rotate(.1turn);
}

60%餅圖的正確打開方式~

----------------- 此處結束----------

當然你要完成12等份,自己還是要在這個思路的基礎上做一些調整的。

現補充一點,還可以使用:

CSS conic-gradient() polyfill(CSS conic-gradient() polyfill)

如:

background: #0ac
repeating-conic-gradient(hsla(0,0%,100%,.2) 0 15deg, hsla(0,0%,100%,0) 0 30deg);

還可以使用在線工具:CIRCULUS.SVG a€」 The SVG Circular Menu Generator

小廣告一下,這裡收集了近100多種在線工具,可以幫你解決一些問題:前端工具_tools_w3cplus

要是還有興趣的話,也可以順便看看這篇文章:用CSS變形創建圓形導航_menu 教程_w3cplus

說完了,不知道是否有用


之前用 sass + 三角函數 畫一個正 18 邊 形實現偽圓周效果,理論上可以等分圓任意份

A Pen by charlee

@-webkit-keyframes search{
$len : 18;
$clockwise: -1;
@for $i from 0 through $len{
$radian : $clockwise * ($i * 360 / $len) * pi() / 180;
#{round($i / $len * 100)}% {
-webkit-transform: translate(round(cos($radian) * $r), round(sin($radian) * $r));
}
}
}


元素結構上不能用12個矩形進行旋轉,因為這樣的話有一半會疊加覆蓋。所以可以用兩個半圓進行遮罩,然後每個半圓里有6個矩形,然後按角度進行旋轉就好啦。之前在張鑫旭的博客里有看到過那兩個半圓做loading動畫的~簡直被萌翻!

附代碼:

html:

&
&
&& && && && && && & &
&& && && && && && & &

sass:

$num: 12;
$light: rgb(255,0,31);
$dark: rgb(0,200,114);
$degree: 360deg / $num;

@for $i from 0 to $num
{
.wrapper .rect:nth-child(#{$i + 1})
{
@if $i % 2 == 1 {
background-color: $light;
}
@else {
background-color: $dark;
}
transform: rotate($degree * $i);
}

}
.wrapper
{
width: 200px;
height: 200px;
border-radius: 50%;
position: relative;
overflow: hidden;
&> div
{
width: 50%; height: 100%;
position:absolute;
overflow: hidden;
}
.box-l
{
top:0; left:0;
.rect
{
transform-origin: 100% 50%;
}
}
.box-r
{
top:0; right:0;
.rect
{
transform-origin: 0 50%;
}
}
.rect
{
width: 100%;
height: 100%;
position: absolute;
top:0; left:0;
}
}


死辦法

&&

.wrapper{
width:200px;
height:200px;
border-radius:50%;
overflow:hidden;
position:relative;
background:yellow;
margin:5em auto;
}
.wrapper div{
width:100px;
height:100px;
transform-origin:left top;
position:absolute;
left:100px;
top:100px;
border:1px solid white;
box-sizing:border-box;
background:#222222;
}

for(var i=0;i&<12;i++){ $("&&").appendTo(".wrapper")
.css({"transform":"rotate("+30*i+"deg)skewX(60deg)"});
}

這邊偷懶了css用:nth-child(n)慢慢寫。

SVG和AI差不多,也可以實現,

就是要考慮減少html元素,box-shadow和偽元素應該可以,css3好像還有個混合模式的功能貌似也可以研究下


clip:rect()

兼容性好


推薦閱讀:

學不會 CSS?
想要學CSS應該如何入門?
CSS transform中的rotate的旋轉中心怎麼設置?
HTML5 的 hidden="hidden" 和CSS的 display:none有什麼區別?
overflow:hidden的問題?

TAG:前端開發 | CSS | CSS3 |