先看來一張圖片,一張帶有進度條效果的圖片,或者美化一下,你能夠當作是充電效果的圖。css
這張圖是繼上篇文章《這樣寫 step 步驟條就輕鬆了》而延伸出來的,在上一篇中提到使用 progress
標籤來實現一個進度條的效果,並無提供任何相對比較具象的 demo。此次,不只有了一個比較具象的 demo(雖然不是特別炫酷),同時,還將會介紹一個新的標籤,一個比 progress
更強大的標籤。html
這個效果其實就是兩個標籤元素疊加而成,爲了造成那種所謂的波浪的效果,會對兩個元素作細微的差別處理,以及在不一樣進度值顯示不一樣的顏色值。web
在這兩張圖中,咱們可以發現不一樣的點是:segmentfault
考慮到但願是經過一個 HTML 元素標籤來實現效果的,那麼這裏用到的波浪就用 ::before
和 ::after
了。用這兩個也是有一些其餘緣由,由於咱們有一個動畫效果須要使用 animation
屬性,可是在僞元素中,後面提到的幾個僞元素在 Chrome 中不支持,不過在 Safari 中倒是能夠的。app
這個圓角是修改了 border-radius
的八個值所得,具體是怎麼樣的一個值,徹底是看心情,好比我是這樣的。less
圖中所示的小工具是很早以前折騰的一個處理圓角的小工具,用這個小工具就是能夠直接拖拉每一個角,而後獲得效果,就不用一個值一個值的手動修改了。工具
直接使用不一樣的 opacity
值,疊加一下就行了。優化
結合 opacity
屬性,再經過 left
或者 margin-left
等值進行位置偏移,最終結合不一樣的 border-radius
就能夠了。動畫
這個就是要結合咱們接下來要提到的 HTML 元素了,該元素可讓咱們在不一樣的 value
值展現不一樣的顏色效果。相比較 progress
元素,會有更多的可配置性。spa
這個就是咱們要了解的 meter
標籤,相比較 progress
而言,多了幾個階段標識,從而也就是有了不一樣的顏色值。
一樣的 meter
標籤在打開 shdow DOM 查看的時候,也是可看到幾個僞元素的存在,相比較 progress
而言,咱們能夠發現,一樣是三層嵌套的結構,可是在 meter
的最後一層嵌套時,僞元素的類名是會根據 value
的狀況而改變的。正由於如此,纔會有不一樣階段的顏色值。
相比 progress
多了 low
、high
以及 optimum
這三個可控制進度展現效果的屬性。不一樣的取值結果最終將直接影響顏色顯示效果。正常狀況下,通常建議是:min ≤ low ≤ high ≤ optimum ≤ max,是的,只是說正常狀況下,若是非正常狀況下,必定要讓 high
小於 low
也不是不能夠,只不過最終顏色的表示就呵呵了。若是 optimum
是在 min 和 low 的區間之間,那麼可能致使的結果就是兩種顏色互調。
上述這兩個跟 progress
中的沒啥區別,就是層級嵌套,包裹着用的。而下面這三個就是有差別了。
從命名能夠看到,主要就是三種不一樣值的顏色表示方式。
<meter min="0" max="10" low="3" high="6" optimum="7" value="2"></meter>
簡單清晰明瞭的 HTML 代碼,後面咱們須要改變就是 value
值就能夠了。
meter { position: relative; width: 200px; height: 50px; margin-top: 100px; border: 5px solid #000; border-radius: 16px; overflow: hidden; appearance: none; }
這部分關鍵的主要就是 position
、overflow
以及 appearance
這三個,appearance
主要做用是爲了修改外觀樣式,而另外兩個則是在下面控制 ::before
和 ::after
的時候所使用的。
meter::after, meter::before { content: ''; position: absolute; top: -200%; left: var(--roundLeft); width: 200px; height: 200px; border-radius: 182px 171px 150px 202px / 200px 219px 141px 149px; background-color: var(--bgc); opacity: 0.3; z-index: 1; animation: 3s linear 0s infinite rotateItem; } meter::before { left: calc(var(--roundLeft) - 5%); border-radius: 151px 132px 178px 118px / 174px 129px 189px 172px; opacity: 0.5; }
在這裏能夠看到,有一個 animation
,因此,還須要補上一個 @keyframes
的關鍵幀。
@keyframes rotateItem { from { transform: rotate(1deg); } to { transform: rotate(360deg); } }
也是很簡單的一段動畫樣式,就是爲了讓那個不規則的圓圈圈轉起來。
心細的你你確定還看到了 --roundLeft
和 --bgc
這兩個 CSS 變量,以及在 ::before
中使用 calc()
計算偏移量的方式。這兩個 CSS 變量的主要做用是後面爲了經過屬性選擇符去控制每一個階段的顏色和位置,好比這樣:
meter[value="0"]::after, meter[value="0"]::before { --roundLeft: -90%; --bgc: #f00; } /* 省略部分 */ meter[value="5"]::after, meter[value="5"]::before { --roundLeft: -50%; --bgc: #f0f; } /* 省略部分 */ meter[value="10"]::after, meter[value="10"]::before { --roundLeft: 0%; --bgc: #0f0; }
前面咱們提到了,是能夠根據 value
值,直接經過三個不一樣的僞元素去改變顏色。若是咱們不是使用 ::before
或者 ::after
的話,的確是能夠的。可是咱們如今是使用了,所以那三個顏色值就沒什麼做用了,也沒法從這樣的層級結構中傳遞到外層做爲繼承使用。
因此,乾脆就直接把這三個顏色值透明化。
meter::-webkit-meter-bar, meter::-webkit-meter-optimum-value, meter::-webkit-meter-even-less-good-value, meter::-webkit-meter-suboptimum-value { background-color: transparent; }
這麼一折騰,最終咱們其實並無利用 meter
組件特性,反而只是結合 value
屬性,經過屬性選擇符而實現了位置的變化。可是這幾個僞元素始終是存在的,只不過這個 demo 沒法證實其可用性。或許是我過於指望想經過每一個值獲得效果,而且又想要加上 animation
動畫效果的關係。
假設,若是 Chrome 中可以很好支持 animation
的動畫效果,就能夠不用利用 ::before
和 ::after
來實現,也就有可能經過 Shadow DOM 中的僞元素了。
在最後,meter
標籤的主要做用是展現,而若是但願有互動效果的話,那麼咱們能夠作的大概可能就有:
:hover
僞類去實現鼠標滑過改變的效果;:checked
實現點擊後切換不一樣顏色的效果;input
輸入改變 meter
的 value
值,而這裏咱們使用了 type='range'
的 input
來實現滑動拖拉改變值;<input type='range' value="2" step="1" min="0" max="10" id="changeMeter" /> <script> const mv = document.getElementById('meterValue'); const cm = document.getElementById('changeMeter'); cm.onchange = function () { mv.value = cm.value; } </script>
最後經過樣式,覆蓋在 meter
上,同時隱藏這個 input
就行了。
#changeMeter { width: 200px; height: 50px; position: absolute; top: 100px; left: 0; z-index: 5; opacity: 0; }
首發我的公衆號: 志語自樂( https://mp.weixin.qq.com/s/r_...