你不知道的 CSS 進(jìn)度條
作者:陳大魚頭 github:KRISACHAN
進(jìn)度條是一個(gè)非常常見的功能,實(shí)現(xiàn)起來也不難,一般我們都會用 div 來實(shí)現(xiàn)。
作為一個(gè)這么常見的需求, whatwg 肯定是不會沒有原生組件提供(雖然有我們也不一定會用),那么就讓我們來康康有哪些有意思的進(jìn)度條實(shí)現(xiàn)方式。
常規(guī)版 — div 一波流
這是比較常規(guī)的實(shí)現(xiàn)方式,先看效果:

源碼如下:
<style>
??.progress1?{
????height:?20px;
????width:?300px;
????background-color:?#f5f5f5;
????border-bottom-right-radius:?10px;
????border-top-right-radius:?10px;
??}
??.progress1::before?{
????counter-reset:?progress?var(--percent,?0);
????content:?counter(progress)?'%\2002';
????display:?block;
????height:?20px;
????line-height:?20px;
????width:?calc(300px?*?var(--percent,?0)?/?100);
????font-size:?12px;
????color:?#fff;
????background-color:?#2486ff;
????text-align:?right;
????white-space:?nowrap;
????overflow:?hidden;
????border-bottom-right-radius:?10px;
????border-top-right-radius:?10px;
??}
??.btn?{
????margin-top:?30px;
??}
style>
<div?id="progress1"?class="progress1">div>
<button?id="btn"?class="btn">點(diǎn)我一下嘛~button>
<script>
??'use?strict';
??let?startTimestamp?=?(new?Date()).getTime();
??let?currentPercentage?=?0;
??let?maxPercentage?=?100;
??let?countDelay?=?100;
??let?timer?=?null;
??let?start?=?false;
??const?percentageChange?=?()?=>?{
????const?currentTimestamp?=?(new?Date()).getTime();
????if?(currentTimestamp?-?startTimestamp?>=?countDelay)?{
??????currentPercentage++;
??????startTimestamp?=?(new?Date()).getTime();
??????progress1.style?=?`--percent:?${currentPercentage}`;
????};
????if?(currentPercentage???????timer?=?window.requestAnimationFrame(percentageChange);
????}?else?{
??????window.cancelAnimationFrame(timer);
????};
??};
??const?clickHander?=?()?=>?{
????if?(!start)?{
??????start?=?true;
??????percentageChange();
????};
??};
??btn.addEventListener('click',?clickHander);
script>
這種方法的核心就是以當(dāng)前盒子為容器,以 源碼如下: 寫完這個(gè) demo 才發(fā)現(xiàn), 另一個(gè)是因?yàn)?range 有專屬語意 —— 范圍,所以它更適合做下面這種事: 以上demo來自:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range 當(dāng)然,上述兩種方式都是模擬進(jìn)度條,實(shí)際上我們并不需要模擬,因?yàn)?whatwg 有為我們提供原生的進(jìn)度條標(biāo)簽 —— 我們先看效果: 實(shí)現(xiàn)如下: 雖然有原生的進(jìn)度條標(biāo)簽,但是規(guī)范里并沒有規(guī)定它的具體表現(xiàn),所以各個(gè)瀏覽器廠商完全可以按照自己的喜好去定制,樣式完全不可控,所以標(biāo)簽雖好。。可用性卻不強(qiáng),有點(diǎn)可惜。 當(dāng)然,能夠?qū)崿F(xiàn)進(jìn)度條功能的標(biāo)簽,除了上面所說的,還有 代碼如下: 這個(gè)標(biāo)簽可能比較陌生,實(shí)際上它跟 本文測評了4種實(shí)現(xiàn)進(jìn)度條的方式,得出的結(jié)論就是 —— 嗯,萬能的 以上 demo 都可以我的 codepen 上查看:https://codepen.io/krischan77/pen/QPezjB 點(diǎn) “查看原文” 也可以看哦~::before 為內(nèi)容填充。用 進(jìn)階版 — input type="range"
是一個(gè)非常實(shí)用的替換元素,不同的 type 可以做不同的事情。第二種就是用 來實(shí)現(xiàn)的。首先我們來看看效果:
<style>
??.progress2[type='range']?{
????display:?block;?
????font:?inherit;
????height:?20px;
????width:?300px;
????pointer-events:?none;
????background-color:?linear-gradient(to?right,?#2376b7?100%,?#FFF?0%);
??}
??.progress2[type='range'],
??.progress2[type='range']::-webkit-slider-thumb?{?
????-webkit-appearance:?none;
??};
??.progress2[type='range']::-webkit-slider-runnable-track?{
????border:?none;
????border-bottom-right-radius:?10px;
????border-top-right-radius:?10px;
????height:?20px;
????width:?300px;
??}
??.btn?{
????margin-top:?30px;
??}
style>
<input?id="progress2"?class="progress2"?type='range'?step="1"?min="0"?max="100"?value="0"/>
<button?id="btn"?class="btn">點(diǎn)我一下嘛~button>
<script>
??'use?strict';
??let?startTimestamp?=?(new?Date()).getTime();
??let?currentPercentage?=?0;
??let?maxPercentage?=?100;
??let?countDelay?=?100;
??let?timer?=?null;
??let?start?=?false;
??let?percentageGap?=?10;
??const?percentageChange?=?()?=>?{
????const?currentTimestamp?=?(new?Date()).getTime();
????if?(currentTimestamp?-?startTimestamp?>=?countDelay)?{
??????currentPercentage++;
??????startTimestamp?=?(new?Date()).getTime();
??????progress2.value?=?currentPercentage;
??????progress2.style.background?=?`linear-gradient(to?right,?#2376b7?${currentPercentage}%,?#FFF?0%`;
????};
????if?(currentPercentage???????timer?=?window.requestAnimationFrame(percentageChange);
????}?else?{
??????window.cancelAnimationFrame(timer);
????};
??};
??const?clickHander?=?()?=>?{
????if?(!start)?{
??????start?=?true;
??????percentageChange();
????};
??};
??btn.addEventListener('click',?clickHander);
script> 并不適合做這個(gè)功能。。一個(gè)是實(shí)現(xiàn)困難,這個(gè) type 組件的每個(gè)元件都可以單獨(dú)修改樣式,但是效果并不是很好。
高級版 — progress 鴨
。
<style>
??.progress3?{
????height:?20px;
????width:?300px;
????-webkit-appearance:?none;
????display:?block;
??}
??.progress3::-webkit-progress-value?{
????background:?linear-gradient(
??????-45deg,?
??????transparent?33%,?
??????rgba(0,?0,?0,?.1)?33%,?
??????rgba(0,0,?0,?.1)?66%,?
??????transparent?66%
????),
??????linear-gradient(
????????to?top,?
????????rgba(255,?255,?255,?.25),?
????????rgba(0,?0,?0,?.25)
??????),
??????linear-gradient(
????????to?left,
????????#09c,
????????#f44);
????border-radius:?2px;?
????background-size:?35px?20px,?100%?100%,?100%?100%;
??}
??.btn?{
????margin-top:?30px;
??}
style>
<progress?id="progress3"?class="progress3"?max="100"?value="0">progress>
<button?id="btn"?class="btn">點(diǎn)我一下嘛~button>
<script>
??'use?strict';
??let?startTimestamp?=?(new?Date()).getTime();
??let?currentPercentage?=?0;
??let?maxPercentage?=?100;
??let?countDelay?=?100;
??let?timer?=?null;
??let?start?=?false;
??const?percentageChange?=?()?=>?{
????const?currentTimestamp?=?(new?Date()).getTime();
????if?(currentTimestamp?-?startTimestamp?>=?countDelay)?{
??????currentPercentage++;
??????startTimestamp?=?(new?Date()).getTime();
??????progress3.setAttribute('value',?currentPercentage);
????};
????if?(currentPercentage???????timer?=?window.requestAnimationFrame(percentageChange);
????}?else?{
??????window.cancelAnimationFrame(timer);
????};
??};
??const?clickHander?=?()?=>?{
????if?(!start)?{
??????start?=?true;
??????percentageChange();
????};
??};
??btn.addEventListener('click',?clickHander);
script>終極版 — meter 賽高
標(biāo)簽。先看效果:
<style>
??.progress4?{
????display:?block;?
????font:?inherit;
????height:?50px;
????width:?300px;
????pointer-events:?none;
??}
??.btn?{
????margin-top:?30px;
??}
style>
<meter?id="progress4"?class="progress4"?low="60"?high="80"?min="0"?max="100"?value="0">meter>
<button?id="btn"?class="btn">點(diǎn)我一下嘛~button>
<script>
??'use?strict';
??let?startTimestamp?=?(new?Date()).getTime();
??let?currentPercentage?=?0;
??let?maxPercentage?=?100;
??let?countDelay?=?100;
??let?timer?=?null;
??let?start?=?false;
??const?percentageChange?=?()?=>?{
????const?currentTimestamp?=?(new?Date()).getTime();
????if?(currentTimestamp?-?startTimestamp?>=?countDelay)?{
??????currentPercentage++;
??????startTimestamp?=?(new?Date()).getTime();
??????progress4.value?=?currentPercentage;
????};
????if?(currentPercentage???????timer?=?window.requestAnimationFrame(percentageChange);
????}?else?{
??????window.cancelAnimationFrame(timer);
????};
??};
??const?clickHander?=?()?=>?{
????if?(!start)?{
??????start?=?true;
??????percentageChange();
????};
??};
??btn.addEventListener('click',?clickHander);
script> 的語義是一樣的,用來顯示已知范圍的標(biāo)量值或者分?jǐn)?shù)值。不一樣的就是。。。它樣式改起來更麻煩。總結(jié)
