CSS確實很重要,且有點奇技淫巧,看起來規則十分簡單,可是創意更重要,如何用css構造出本身想要的效果,寫的代碼好看優雅十分重要。 在看了不借助Echarts等圖形框架原生JS快速實現折線圖效果並本身從新實現了之後,實在是感慨CSS的強大之處,並做出記錄。css
先上結果圖: git
總結下本身以爲關於幾點比較難以理解的點:github
<style>
.chartX {
width: 670px;
height: 250px;
position: relative;
border-top: 1px solid #ccc;
margin: 100px auto;
background: linear-gradient(to top, #ccc 0, #ccc 1px, transparent 1px);
background-size: 100% 50px;
font-size: 0;
text-align: center;
}
</style>
<div class="chartX">
</div>
複製代碼
再上代碼:bash
<style>
.chartX::after {
content: '100 \a 80 \a 60 \a 40 \a 20 \a 0 ';
line-height: 50px;
white-space: pre;
position: absolute;
font-size: 12px;
top: -25px;
left: -2rem;
text-align: right;
}
</style>
複製代碼
最後解釋: 咱們應該讓每個元素佔據一行,且這一行的高度和背景橫線之間的間距相等而後讓其中的文字居中顯示,這樣就有6行文字分別與背景線對齊了。 因此咱們要作的第一點就是寫出6行文字:即代碼中的app
content: '100 \a 80 \a 60 \a 40 \a 20 \a 0 ';
white-space: pre;
複製代碼
content定義了內容,‘\a' 爲換行,同時設置 white-space: pre;
保持文字的空格符和換行,說白了就是讓每一個數字間換行,因而就有了從上至下排列的 100 80 60 40 20 0這樣一列數字。框架
上一步完成後就須要保證每一行的高度爲橫線間距相等在本文中即爲:50px。怎麼作呢?其實在個人以前一篇文章中的關於CSS:line-height中有了答案,在沒有height屬性下,咱們經過line-height來控制盒子的高度,即:dom
line-height: 50px;
複製代碼
這樣每一行都是50px的高度,再將盒子總體往上移動25px就作到了使得背景橫線與line-height的中線處於同一高度,即數字被橫線縱向對半分割。wordpress
完成了座標系的繪製後,應該實現柱狀圖的繪製學習
如何實現下面的這個效果呢?ui
幾個點注意一下:
直接上代碼:
<style>
.result-bg {
display: inline-block;
position: relative;
width: calc((100% - 16px * 13) / 12);
height: 100%;
background: #eee;
}
.result-bg::after {
content: attr(data-month)'月';
font-size: 12px;
color: grey;
position: absolute;
bottom: -1rem;
left: 0;
right: 0;
}
.dot {
border: 2px solid #97cd74;
width: 6px;
height: 6px;
border-radius: 50%;
background: #fff;
position: absolute;
left: 0;
right: 0;
top: 15px;
margin: auto;
}
</style>
<div class="chartX">
<div class="result-bg" data-month="1">
<div class="result-bar" style="height: 82%">
<div class="dot"></div>
</div>
</div>
<div>
複製代碼
再來解釋: 首先式底部文字的問題: 使用僞元素after的content屬性 這裏要普及如下,content屬性中能夠使用attr了,即獲取元素的自定義屬性值,因此纔有了以上代碼:
content: attr(data-month)'月';
<div class="result-bg" data-month="1">
複製代碼
配合absolute定位天然繪出了文字
至於中間的點的問題: 畫出一個這個樣式的點不稀奇,如何讓它居中呢?參考個人另外一篇文章:關於CSS:關於absolute定位 即讓bounding-box的寬度等同於父元素高度,而後咱們讓圓點的margin爲auto天然就居中啦,表現代碼如上,不作多餘解釋,須要讀者自行嘗試代碼。
須要實現下面的效果:
這裏就真的只能用到js了,由於要手動計算距離和旋轉的角度啊
總結關鍵點:
以上都不是難點,須要注意的是,rotate的時候須要以左邊端點爲中心進行旋轉。先上線段的CSS代碼:
<style>
.dot i {
display: inline-block;
box-sizing: border-box;
position: absolute;
left: 50%;
top: 50%;
margin-top: -1px;
height: 2px;
background: #97cd74;
border-right: 3px solid #fff;
border-left: 3px solid #fff;
transform-origin: left;
z-index: 1;
}
</style>
<div class="chartX">
<div class="result-bg" data-month="11">
<div class="result-bar" style="height: 82%">
<div class="dot">
<i></i>
</div>
</div>
</div>
<div class="result-bg" data-month="12">
<div class="result-bar" style="height: 62%">
<div class="dot">
<i></i>
</div>
</div>
</div>
<div>
複製代碼
i標籤就是咱們的線段啦,而後爲線段設置背景顏色便可 其中的transform-origin:left
即爲設置旋轉中心點
最後只須要用js來動態的給每一個柱子添加i標籤,並設置其長度和旋轉角度就能夠了,代碼以下:
const bars = document.querySelectorAll('.result-bar .dot')
bars.forEach((bar, index) => {
const nextBar = bars[index + 1]
if (!nextBar) {
return
}
let elLine = bar.querySelector('i')
if (!elLine) {
elLine = document.createElement('i')
elLine.setAttribute('line', '')
bar.appendChild(elLine)
}
// 計算線段長度和旋轉弧度
let boundThis = bar.getBoundingClientRect(),
boundNext = nextBar.getBoundingClientRect(),
x1 = boundThis.left,
y1 = boundThis.top,
x2 = boundNext.left,
y2 = boundNext.top,
distance = Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)),
radius = Math.atan((y2 - y1) / (x2 - x1))
console.log(distance, radius)
elLine.style.width = `${distance}px`
elLine.style.transform=`rotate(${radius}rad)`
})
複製代碼
至此結束。
以上實現方式真的只是拾人牙慧,可以從張鑫旭前輩的代碼中學習到這麼多東西真的感到敬畏。 以上完整代碼均在github中,歡迎指正學習。