本篇文章給大家介紹使用CSS的實(shí)用小技巧,了解一下CSS自動(dòng)補(bǔ)全字符串的幾種方法,希望對(duì)大家有所幫助!
很多時(shí)候都會(huì)碰到字符串補(bǔ)全的需求,典型的例子就時(shí)間或者日期中的補(bǔ)零操作,例如
2021-12-31 2022-03-03
通常的做法是
if (num < 10) { num = '0' + num }
后來(lái),JS 中出現(xiàn)了原生的補(bǔ)全方法padStart()
和padEnd()
,如下
'3'.padStart(2, '0') // 結(jié)果是 ’03‘ '12'.padStart(2, '0') // 結(jié)果是 ’12‘
其實(shí)呢,在 CSS 中也是可以實(shí)現(xiàn)這樣的效果的,并且有多種方案,下面一起看看吧,相信能有不一樣的體會(huì)?!就扑]學(xué)習(xí):css視頻教程】
一、flex-end 對(duì)齊
先介紹一個(gè)比較容易理解的方案,也非常簡(jiǎn)單,假設(shè) HTML 是這樣的
<span>2</span> - <span>28</span>
一般情況下,還會(huì)設(shè)置等寬字體,看起來(lái)更加協(xié)調(diào)、美觀
span{ font-family: Consolas, Monaco, monospace; }
我們需要在數(shù)字前用偽元素生成一個(gè)“0”
span::before{ content: '0' }
接下來(lái),給元素設(shè)置一個(gè)固定寬度,這里由于是等寬字體,所以可以直接設(shè)置為2ch
,注意這個(gè)ch
單位,它表示字符0
的寬度(有興趣的可以參考這篇文章:等寬字體在web布局中應(yīng)用以及CSS3 ch單位嘿嘿),然后設(shè)置右對(duì)齊就行了
span{ /**/ display: inline-flex; width: 2ch; justify-content: flex-end; }
原理很簡(jiǎn)單,在 2 個(gè)字符寬度的空間里放置 3 個(gè)字符,以右對(duì)齊的方式,是不是就自動(dòng)把最左邊的 0 給擠出去了?然后超出隱藏就可以了
完整代碼如下
span::before{ content: '0' } span{ display: inline-flex; width: 2ch; justify-content: flex-end; overflow: hidden; }
二、CSS 變量動(dòng)態(tài)計(jì)算
由于 CSS 無(wú)法獲取標(biāo)簽的文本內(nèi)容,所以這里需要構(gòu)建一個(gè) CSS 變量傳遞下去,如下
<span style="--num:2">2</span> - <span style="--num:12">28</span>
通過(guò) var(--num)
拿到變量以后,就可以進(jìn)行一系列的邏輯判斷了,那么,如何在小于 10 的情況下自動(dòng)補(bǔ)零呢?
同樣我們需要在數(shù)字前用偽元素生成一個(gè)“0”
span::before{ content: '0' }
然后,只需要根據(jù) CSS 變量動(dòng)態(tài)隱藏這個(gè)偽元素就行了,先設(shè)置透明度,如下
span::before{ /**/ opacity: calc(10 - var(--num)); }
效果如下
具體的邏輯就是
-
當(dāng)
--num
等于 10 時(shí),透明度的計(jì)算值就是 0,直接按照 0 來(lái)渲染 -
當(dāng)
--num
大于 10 時(shí),透明度的計(jì)算值就是負(fù)數(shù)值,會(huì)按照 0 來(lái)渲染 -
當(dāng)
--num
小于 10 時(shí),透明度的計(jì)算值就是大于等于1的值,會(huì)按照 1 來(lái)渲染
所以,最終的表現(xiàn)就是當(dāng)大于等于10時(shí)不可見(jiàn),小于10的時(shí)候可見(jiàn)
但是,這樣還是有點(diǎn)問(wèn)題的,透明度不會(huì)影響元素的位置,如下
如何消除這個(gè)位置呢?方法有很多,這里采用 margin-left
的方式,如下
span::before{ /**/ margin-left: clamp(-1ch, calc((9 - var(--num)) * 1ch),0ch); }
這里用到了clamp,你可以理解為一個(gè)區(qū)間,有 3 個(gè)值 [Min, Val, Max]
,前后分別是最小、最大值,中間是可變值(注意這里是和 9 比較),所以這里的邏輯就是
- 當(dāng)
--num
大于等于 10 時(shí),假設(shè)為 15,中間 calc 值計(jì)算為 -5ch,clamp 取值為最小值 -1ch - 當(dāng)
--num
小于 10 時(shí),假設(shè)為 5,中間 calc 值計(jì)算為 5ch,clamp 取值為最大值 0ch
所以,最終的表現(xiàn)就是當(dāng)大于等于10時(shí)margin-left為-1ch,小于10的時(shí)候margin-left為0
這樣就比較完美了
完整代碼如下
span::before{ content: '0'; opacity: calc(10 - var(--num)); margin-left: clamp(-1ch, calc((9 - var(--num)) * 1ch),0ch); }
三、定義計(jì)數(shù)器樣式
利用計(jì)數(shù)器也能實(shí)現(xiàn)這一效果,首先看默認(rèn)的計(jì)數(shù)器效果,我們需要隱藏原有的文字,利用計(jì)數(shù)器讓 CSS 變量通過(guò)偽元素展示出來(lái),關(guān)于這個(gè)技巧,可以參考這篇文章:小tips: 如何借助content屬性顯示CSS var變量值,如下
span::before{ counter-reset: num var(--num); content: counter(num); }
接下來(lái)需要用到 counter
的第 2 個(gè)參數(shù) ,計(jì)數(shù)器樣式。這是干什么的呢?相信大家都用過(guò)一個(gè)屬性 list-style-type,就是和這個(gè)相通的,可以定義序列的樣式,比如按照小寫(xiě)英文字母的順序
list-style-type: lower-latin;
這里我們需要一個(gè) 10 以?xún)?nèi)自動(dòng)補(bǔ)零的計(jì)數(shù)器,剛好有個(gè)現(xiàn)成的,叫做 decimal-leading-zero
,翻譯過(guò)來(lái)就是,十進(jìn)制前置零
list-style-type: decimal-leading-zero;
回到這里,需要做的就很簡(jiǎn)單了,補(bǔ)上這個(gè)參數(shù)就行了,完整代碼如下
span::before{ counter-reset: num var(--num); content: counter(num, decimal-leading-zero); }
效果如下
四、計(jì)數(shù)器的擴(kuò)展
上面的計(jì)數(shù)器只適用于2位數(shù)的,如果需要 3 位數(shù)的怎么辦呢? 例如
001、002、...、010、012、...、098、099、100
JS 中的 padStart
可以指定填充后的位數(shù)
'1'.padStart(3, '0') // 結(jié)果是 ’001‘ '99'.padStart(3, '0') // 結(jié)果是 ’099‘ '101'.padStart(3, '0') // 結(jié)果是 ’101‘
其實(shí),CSS 中也是有這樣的能力的,叫做@counter-style/pad
,嚴(yán)格來(lái)說(shuō),這才是官方的補(bǔ)全方案,語(yǔ)法也非常類(lèi)似
pad: 3 "0";
但是,這個(gè)需要用在自定義計(jì)數(shù)器上,也就是@counter-style,有興趣的可以參考張老師的這篇文章:CSS @counter-style規(guī)則詳細(xì)介紹,這里簡(jiǎn)單介紹一下用法,假設(shè)定義一個(gè)計(jì)數(shù)器叫做pad-num
,實(shí)現(xiàn)如下
@counter-style pad-num { system: extends numeric; pad: 3 "0"; }
語(yǔ)法是這樣的:這里的system
表示“系統(tǒng)”,就是內(nèi)置的一些計(jì)數(shù)器,比如這里用到了extends numeric
,后面的numeric
表示數(shù)字技術(shù)系統(tǒng),前面的extends
表示擴(kuò)展,以這個(gè)為基礎(chǔ),然后pad: 3 "0"
就和 JS 的意義一樣了,表示不足 3 位的地方補(bǔ)“0”
然后運(yùn)用到計(jì)數(shù)器中:
span::before{ counter-reset: num var(--num); content: counter(num, pad-num); }
效果如下:
當(dāng)然,這個(gè)兼容性略差,根據(jù)實(shí)際需求即可
以上完整代碼可以訪問(wèn):
https://codepen.io/xboxyan/pen/YzEdbwj
五、總結(jié)一下
以上介紹了3種 CSS 字符串補(bǔ)全方法,是不是又學(xué)到了幾個(gè)小技巧呢?這幾個(gè)方法各有千秋,比較一下各自?xún)?yōu)缺點(diǎn):
-
第一種方案非常容易理解,也容易擴(kuò)展,如果需要補(bǔ)全 3 位,只需要改變整體寬度即可,不足之處在于依賴(lài)等寬字體。
-
第二種方案比較符合 JS 邏輯,比較靈活,不足在于計(jì)算比較啰嗦,而且還要考慮 CSS 取值的容錯(cuò)性。
-
第三種方案是我比較推薦的了,無(wú)需計(jì)算,也不依賴(lài)布局,可能知道的同學(xué)不多,而且如果要自定義計(jì)數(shù)器,兼容性有點(diǎn)差。
關(guān)于 CSS 實(shí)現(xiàn)的優(yōu)點(diǎn),有很多,比如更容易維護(hù)、幾乎不會(huì)報(bào)錯(cuò)、代碼更加簡(jiǎn)潔等等,如果你學(xué)會(huì)了,趕緊在項(xiàng)目中用起來(lái)吧。
(學(xué)習(xí)視頻分享:web前端)