乐趣区

关于前端:CSS-也能自动补全字符串

欢送关注我的公众号:前端侦探

很多时候都会碰到字符串补全的需要,典型的例子就工夫或者日期中的补零操作,例如

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 字符串补全办法,是不是又学到了几个小技巧呢?这几个办法各有千秋,比拟一下各自优缺点:

  1. 第一种计划非常容易了解,也容易扩大,如果须要补全 3 位,只须要扭转整体宽度即可,不足之处在于依赖等宽字体。
  2. 第二种计划比拟合乎 JS 逻辑,比拟灵便,有余在于计算比拟啰嗦,而且还要思考 CSS 取值的容错性。
  3. 第三种计划是我比拟举荐的了,无需计算,也不依赖布局,可能晓得的同学不多,而且如果要自定义计数器,兼容性有点差。

对于 CSS 实现的长处,有很多,比方更容易保护、简直不会报错、代码更加简洁等等,如果你学会了,连忙在我的项目中用起来吧。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探

退出移动版