欢送关注我的公众号:前端侦探
很多时候都会碰到字符串补全的需要,典型的例子就工夫或者日期中的补零操作,例如
2021-12-31
2022-03-03
通常的做法是
if (num < 10) {num = '0' + num}
起初,JS 中呈现了原生的补全办法 padStart()
和padEnd()
,如下
'3'.padStart(2, '0')
// 后果是’03‘'12'.padStart(2, '0')
// 后果是’12‘
其实呢,在 CSS 中也是能够实现这样的成果的,并且有多种计划,上面一起看看吧,置信能有不一样的领会
一、flex-end 对齐
先介绍一个比拟容易了解的计划,也非常简单,假如 HTML 是这样的
<span>2</span>
-
<span>28</span>
个别状况下,还会设置等宽字体,看起来更加协调、好看
span{font-family: Consolas, Monaco, monospace;}
咱们须要在数字前用伪元素生成一个“0”
span::before{content: '0'}
接下来,给元素设置一个固定宽度,这里因为是等宽字体,所以能够间接设置为 2ch
,留神这个ch
单位,它示意字符 0
的宽度(有趣味的能够参考这篇文章:等宽字体在 web 布局中利用以及 CSS3 ch 单位嘿嘿),而后设置右对齐就行了
span{
/**/
display: inline-flex;
width: 2ch;
justify-content: flex-end;
}
原理很简略,在 2 个字符宽度的空间里搁置 3 个字符,以右对齐的形式,是不是就主动把最右边的 0 给挤出去了?而后超出暗藏就能够了
残缺代码如下
span::before{content: '0'}
span{
display: inline-flex;
width: 2ch;
justify-content: flex-end;
overflow: hidden;
}
二、CSS 变量动静计算
因为 CSS 无奈获取标签的文本内容,所以这里须要构建一个 CSS 变量传递上来,如下
<span style="--num:2">2</span>
-
<span style="--num:12">28</span>
通过 var(--num)
拿到变量当前,就能够进行一系列的逻辑判断了,那么,如何在小于 10 的状况下主动补零呢?
同样咱们须要在数字前用伪元素生成一个“0”
span::before{content: '0'}
而后,只须要依据 CSS 变量动静暗藏这个伪元素就行了,先设置透明度,如下
span::before{
/**/
opacity: calc(10 - var(--num));
}
成果如下
具体的逻辑就是
- 当
--num
等于 10 时,透明度的计算值就是 0,间接依照 0 来渲染 - 当
--num
大于 10 时,透明度的计算值就是 负数值,会依照 0 来渲染 - 当
--num
小于 10 时,透明度的计算值就是 大于等于 1 的值,会依照 1 来渲染
所以,最终的体现就是 当大于等于 10 时不可见,小于 10 的时候可见
然而,这样还是有点问题的,透明度不会影响元素的地位,如下
如何打消这个地位呢?办法有很多,这里采纳 margin-left
的形式,如下
span::before{
/**/
margin-left: clamp(-1ch, calc((9 - var(--num)) * 1ch),0ch);}
这里用到了 clamp,你能够了解为一个区间,有 3 个值 [Min, Val, Max]
,前后别离是最小、最大值,两头是可变值(留神这里是和 9 比拟),所以这里的逻辑就是
- 当
--num
大于等于 10 时,假如为 15,两头 calc 值计算为 -5ch,clamp 取值为最小值 -1ch - 当
--num
小于 10 时,假如为 5,两头 calc 值计算为 5ch,clamp 取值为最大值 0ch
所以,最终的体现就是 当大于等于 10 时 margin-left 为 -1ch,小于 10 的时候 margin-left 为 0
这样就比拟完满了
残缺代码如下
span::before{
content: '0';
opacity: calc(10 - var(--num));
margin-left: clamp(-1ch, calc((9 - var(--num)) * 1ch),0ch);}
三、定义计数器款式
利用计数器也能实现这一成果,首先看默认的计数器成果,咱们须要暗藏原有的文字,利用计数器让 CSS 变量通过伪元素展现进去,对于这个技巧,能够参考这篇文章:小 tips: 如何借助 content 属性显示 CSS var 变量值,如下
span::before{counter-reset: num var(--num);
content: counter(num);
}
接下来须要用到 counter
的第 2 个参数 <counter-style>,计数器款式。这是干什么的呢?置信大家都用过一个属性 list-style-type,就是和这个相通的,能够定义序列的款式,比方依照小写英文字母的程序
list-style-type: lower-latin;
这里咱们须要一个 10 以内主动补零的计数器,刚好有个现成的,叫做 decimal-leading-zero
,翻译过去就是,十进制前置零
list-style-type: decimal-leading-zero;
回到这里,须要做的就很简略了,补上这个参数就行了,残缺代码如下
span::before{counter-reset: num var(--num);
content: counter(num, decimal-leading-zero);
}
成果如下
四、计数器的扩大
下面的计数器只实用于 2 位数的,如果须要 3 位数的怎么办呢? 例如
001、002、...、010、012、...、098、099、100
JS 中的 padStart
能够指定填充后的位数
'1'.padStart(3, '0')
// 后果是’001‘'99'.padStart(3, '0')
// 后果是’099‘'101'.padStart(3, '0')
// 后果是’101‘
其实,CSS 中也是有这样的能力的,叫做 @counter-style/pad,严格来说,这才是官网的补全计划,语法也十分相似
pad: 3 "0";
然而,这个须要用在自定义计数器上,也就是 @counter-style,有趣味的能够参考张老师的这篇文章:CSS @counter-style 规定具体介绍,这里简略介绍一下用法,假如定义一个计数器叫做pad-num
,实现如下
@counter-style pad-num {
system: extends numeric;
pad: 3 "0";
}
语法是这样的:这里的 system
示意“零碎”,就是内置的一些计数器,比方这里用到了 extends numeric
,前面的numeric
示意数字技术零碎,后面的 extends
示意扩大,以这个为根底,而后 pad: 3 "0"
就和 JS 的意义一样了,示意有余 3 位的中央补“0”
而后使用到计数器中:
span::before{counter-reset: num var(--num);
content: counter(num, pad-num);
}
成果如下:
当然,这个兼容性略差,依据理论需要即可
以上残缺代码能够拜访 CSS pad(codepen.io)
五、总结一下
以上介绍了 3 种 CSS 字符串补全办法,是不是又学到了几个小技巧呢?这几个办法各有千秋,比拟一下各自优缺点:
- 第一种计划非常容易了解,也容易扩大,如果须要补全 3 位,只须要扭转整体宽度即可,不足之处在于依赖等宽字体。
- 第二种计划比拟合乎 JS 逻辑,比拟灵便,有余在于计算比拟啰嗦,而且还要思考 CSS 取值的容错性。
- 第三种计划是我比拟举荐的了,无需计算,也不依赖布局,可能晓得的同学不多,而且如果要自定义计数器,兼容性有点差。
对于 CSS 实现的长处,有很多,比方更容易保护、简直不会报错、代码更加简洁等等,如果你学会了,连忙在我的项目中用起来吧。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探