本文由做者鄒欣華受權網易雲社區發佈。css
有一個在郵件中用餅圖直觀地顯示用戶的各項消費比例的需求。郵箱中不能用js,純css實現餅圖,只能經過後端模版渲染數據,因此數據越少越簡單越好。css3
想到css3的transform的rotate屬性,rotate經過對指定的角度參數對元素指定一個角度的旋轉。圓形的話用border-radius就能夠實現,可是怎樣經過旋轉生成餅圖。一個完整的圓不論怎樣旋轉都還只是一個圓,達不到要讓每個模塊按比例顯示出來的效果。可是能夠用多個扇形組合成一個圓,而後經過旋轉的角度差,顯示各自的比例。旋轉之後顯示須要的部分,不須要的部分就要隱藏起來。又聯想到了css2的clip屬性。能夠利用clip裁剪出想要的部分,rotate旋轉出百分佔比的區域,其他的部分經過透明遮罩隱藏起來,border-radius屬性實現圓形效果。後端
第一步獲得一個小扇形。安全
裁剪圓的右邊一半(clip:rect(0px,100px,200px,0px)),而且將右邊半圓旋轉20度(transform:rotate(20deg))。服務器
第二步,接着生成多個扇形合成一個完整的圓。由於需求中不肯定哪些內容須要展現,可是知道各自的數量以及總數,就能夠計算出各自的佔比,遮罩旋轉的角度是前面全部扇形旋轉角度的累加,扇形旋轉的角度就是其百分比乘以360得出。源碼分析
這裏須要提早在css中把全部可能出現的種類及對應的顏色定義好。clip屬性只能在設置了」position:absolute」或者」position:fixed」屬性起做用佈局
透明遮罩的公共樣式.net
.hold {orm
position:absolute;cdn
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
}
扇形區域的公共樣式
.pie {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,100px,200px,0px);
border-radius:100px;
}
第三步,將全部的扇形渲染完成就是一個完整的餅圖了。由於數據是動態的因此須要特殊處理一下佔比大於50%的狀況。若是第一個扇形佔比大於50%,須要旋轉180度以後,再寫一個一樣顏色的扇形區域接着以前的旋轉剩餘的角度。旋轉角度經過後端模版計算出來,因此經過style來定義。
<div id="NVS" >
<div style="transform:rotate(180deg);"></div>
</div>
<div id="NVS" style="transform:rotate(180deg);">
<div style="transform:rotate(19.8deg);"></div>
</div>
還有一種特殊狀況是扇形旋轉的總角度和大於180,可是該扇形區域還有一部分未顯示,須要將該部分旋轉180減去前面部分的總和再寫一個一樣顏色的扇形區域接着以前的旋轉該部分剩餘的角度。
<div id="NLB" >
<div style="transform:rotate(60deg);"></div>
</div>
<div id="CDN" style="transform:rotate(60deg);">
<div style="transform:rotate(120deg);"></div>
</div>
<div id="CDN" style="transform:rotate(180deg);">
<div style="transform:rotate(90deg);"></div>
</div>
最後的結果圖。
第一次接觸到郵件中的需求,後來發現郵箱客戶端css3的transform特性不支持,最後只能將餅圖轉換成圖片放在頁面中。而且考慮要outlook等郵箱客戶端內核的不一樣,最好用table佈局,而且圖片要在頁面中用img標籤引入,譬如margin這樣的屬性會失效等。
以上只是個人思路與作法,歡迎各路大神支招改進。
附上各郵箱對css的支持狀況:https://www.campaignmonitor.com/css/
免費領取驗證碼、內容安全、短信發送、直播點播體驗包及雲服務器等套餐
更多網易技術、產品、運營經驗分享請訪問網易雲社區。
相關文章:
【推薦】 Obfuscator-llvm源碼分析