当前位置:首页 > 科技  > 软件

纯 CSS 实现标签自动显示超出数量

来源: 责编: 时间:2024-05-09 09:26:18 87观看
导读现代CSS强大的令人难以置信。这次我们来用 CSS 实现这样一个功能:有多个宽度不同的标签水平排列,当外层宽度不足时,会提示超出的数量,演示效果如下图片如果让我用 JavaScript来实现估计都有点折腾,毕竟宽度都是动态的,要监

现代CSS强大的令人难以置信。yF028资讯网——每日最新资讯28at.com

这次我们来用 CSS 实现这样一个功能:有多个宽度不同的标签水平排列,当外层宽度不足时,会提示超出的数量,演示效果如下yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

如果让我用 JavaScript来实现估计都有点折腾,毕竟宽度都是动态的,要监听各部分的尺寸变化,包括标签的位置和外层的宽度,总之不是一两行代码就能搞定的。yF028资讯网——每日最新资讯28at.com

现如今,纯CSS也能完美的实现这样的效果,而且比 JS 实现更加简单,一起来看看吧yF028资讯网——每日最新资讯28at.com

一、CSS 实现思路

很多时候,CSS并没有直接的实现方式,需要“绕”点弯路,将需求拆分成很多小点,然后逐一突破。yF028资讯网——每日最新资讯28at.com

回到本文这里,其实有几个问题需要考虑:yF028资讯网——每日最新资讯28at.com

  1. CSS 如何动态累计数字?
  2. CSS 如何知道哪些元素在容器之外?
  3. CSS 如何区分是否溢出(显示数量)

关于第3点,其实在之前这篇文章中有详细介绍,有兴趣可以回顾一下,非常有意思yF028资讯网——每日最新资讯28at.com

纯 CSS 检测文本是否溢出yF028资讯网——每日最新资讯28at.com

yF028资讯网——每日最新资讯28at.com

那么第一点,CSS有没有什么方式可以统计数量呢?yF028资讯网——每日最新资讯28at.com

没错,相信很多小伙伴已经猜到了,就是利用 CSS计数器,示意如下yF028资讯网——每日最新资讯28at.com

counter-reset: num var(--num);counter-increment: num;::after{	content: "+"counter(num);}

关于计数器,我之前也在很多文章中有用到yF028资讯网——每日最新资讯28at.com

你可能不需要 JS!CSS实现一个计时器yF028资讯网——每日最新资讯28at.com

如何让CSS计数器支持小数的动态变化?yF028资讯网——每日最新资讯28at.com

还在使用定时器吗?CSS 也能实现电子时钟yF028资讯网——每日最新资讯28at.com

动画合成小技巧!CSS 实现动感的倒计时效果yF028资讯网——每日最新资讯28at.com

自定义计数器小技巧!CSS 实现长按点赞累积动画yF028资讯网——每日最新资讯28at.com

yF028资讯网——每日最新资讯28at.com

然后是第二点,CSS有什么方式可以知道元素是出去了还是在视野之内呢?yF028资讯网——每日最新资讯28at.com

如果是用 JS来判断的话,最稳妥的方式应该Intersection Observer(交叉观察者),相信很多同学都用过,这个在图片懒加载非常有用yF028资讯网——每日最新资讯28at.com

交叉观察器 API - Web API 接口参考 | MDN (mozilla.org)[1]yF028资讯网——每日最新资讯28at.com

yF028资讯网——每日最新资讯28at.com

那么,CSS中有什么类似的呢?没错,还是之前提到过的CSS滚动驱动动画。yF028资讯网——每日最新资讯28at.com

不过这里用到的是视图进度,也就是关注的是元素自身位置,元素进入到容器范围之内就会触发动画,非常类似 JS中的Intersection ObserveryF028资讯网——每日最新资讯28at.com

tag{  animation: appear;  animation-timeline: view(inline);  animation-range: contain;}@keyframes appear{  to {    background-color: #9747FF;  }}

这里就不详细介绍了,有兴趣回顾之前这篇文章yF028资讯网——每日最新资讯28at.com

CSS 滚动驱动动画终于正式支持了~ yF028资讯网——每日最新资讯28at.com

yF028资讯网——每日最新资讯28at.com

好了,关键原理就这些了,我们需要做的就是想办法将「计数器」和「元素进出容器范围」关联起来就行了,接着往下看yF028资讯网——每日最新资讯28at.com

二、CSS 计数器

利用 CSS 计数器,我们可以很轻松的统计元素的数量。yF028资讯网——每日最新资讯28at.com

先简单布局一下文章开头的例子,HTML如下所示yF028资讯网——每日最新资讯28at.com

<div class="con">  <a class="tag">HTML</a>  <a class="tag">CSS</a>  <a class="tag">JavaScript</a>  <a class="tag">Flutter</a>  <a class="tag">Vue</a>  <a class="tag">React</a>  <a class="tag">Svelte</a></div><span class="num"></span><!--用来计数的标签-->

然后美化一下yF028资讯网——每日最新资讯28at.com

.con{  display: flex;  gap: 5px;  padding: 5px;  overflow: hidden;}.tag{  padding: .2em .5em;  background-color: #c49ef5;  color: #fff;  border-radius: 4px;  animation: appear;}.num::after{  content: "+0";  padding: .2em .5em;  background-color: #FFE8A3;  color: #191919;  border-radius: 4px;}

这样就得到了水平排列的 tag 布局(超出隐藏),后面跟一个数字yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

现在我们定义一个计数器,然后通过每个tag进行累计,有多个tag相当于多少次累加,最后在::after中显示出来yF028资讯网——每日最新资讯28at.com

.con{  counter-reset: num;  /*计数器初始值,默认为0*/}.tag{  counter-increment: num; /*计数器增量值,默认为1*/}.num::after{  content: "+"counter(num); }

默认计数器的起始值是 0,每次累计是1,所以这里最后得到了7,这样就能实时统计元素的数量了yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

当然,我们也可以自定义这些默认值,比如yF028资讯网——每日最新资讯28at.com

.con{  counter-reset: num 10;}.tag{  counter-increment: num -1;}

这种情况下,起始值是10,增量值是-1,所以最后得到了3,如下yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

那么,该如何统计容器之外的标签数量呢?yF028资讯网——每日最新资讯28at.com

三、CSS 滚动驱动动画

这里我们要利用CSS 视图进度时间轴,也就是观察元素自身的位置,在进入到容器范围之内执行动画。yF028资讯网——每日最新资讯28at.com

拿上面这个例子,我们给标签添加一个动画,让标签在进入到容器之内时变个颜色,实现如下yF028资讯网——每日最新资讯28at.com

.tag{  animation: appear;  animation-timeline: view(inline);}@keyframes appear{  to {    background-color: #4d47ff;  }}

由于是水平方向,所以这里需要设置view(inline) ,效果如下yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

好像不是很明显?这是因为动画是在整个视区内过渡的,我们可以改变动画时间线的区间animation-range,让这个动画在进出的一瞬间就变化yF028资讯网——每日最新资讯28at.com

.tag{  animation: appear;  animation-timeline: view(inline);  animation-range: contain;}@keyframes appear{  from,to {    background-color: #4d47ff;  }}

效果如下yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

那么,这个效果和前面的计数器有什么关联呢?yF028资讯网——每日最新资讯28at.com

从效果上来看,在视区内会执行一个动画,如果在这个动画中加入计数器的累加会怎么样呢?先去除原先的累加器yF028资讯网——每日最新资讯28at.com

.tag{  /* counter-increment: num; */}@keyframes appear{  from,to {    background-color: #4d47ff;    counter-increment: num;  }}

效果如下yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

可以看到计数器已经生效了,不过现在统计的在「可视区内」标签的数量。而我们要统计的是「可视区外」的数量,好像反过来了,如何实现呢?yF028资讯网——每日最新资讯28at.com

这里有两种思路。yF028资讯网——每日最新资讯28at.com

第一种,用总数减去可视区内的数量,不就行了吗?由于现在动画是针对可视区内的,我们可以给计数器设置一个初始值,就是总量,然后动画中给累加值设置为-1,就相当于减去当前数量了,实现如下yF028资讯网——每日最新资讯28at.com

.con{	counter-reset: num 7;}@keyframes appear{  from,to {    background-color: #4d47ff;    counter-increment: num -1;  }}

这样就完美统计出了可视区外的数量了yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

还有一种方式,我觉得更加巧妙,需要反向思考。原理是重置当前的累加值,比如默认情况下,正常累加,进入可视范围,把累加值设置为0,不就相当于可视区外的正常累加了吗?yF028资讯网——每日最新资讯28at.com

.tag{  counter-increment: num;}@keyframes appear{  from,to {    background-color: #4d47ff;    counter-increment: num 0;  }}

同样能达到相同的效果yF028资讯网——每日最新资讯28at.com

图片图片yF028资讯网——每日最新资讯28at.com

现在基本已经达到我们需要的效果了yF028资讯网——每日最新资讯28at.com

四、其他细节修正

首先是,在超出范围时,需要在边缘出添加一个半透明蒙层,这样体验效果会更好。yF028资讯网——每日最新资讯28at.com

半透明蒙层很好实现,只需要添加一个水平渐变的mask遮罩就行了yF028资讯网——每日最新资讯28at.com

.con{  -webkit-mask: linear-gradient(to right, #fff calc(100% - 30px), transparent);}

效果如下yF028资讯网——每日最新资讯28at.com

那么,如何在没有超出时,不出现这个遮罩呢?yF028资讯网——每日最新资讯28at.com

这个其实在之前的文章中有详细介绍了,建议回顾一下yF028资讯网——每日最新资讯28at.com

纯 CSS 检测文本是否溢出yF028资讯网——每日最新资讯28at.com

yF028资讯网——每日最新资讯28at.com

利用CSS滚动驱动动画,可以检测容器是否可滚动,也就是是否超出。所以我们只需要将遮罩放在滚动驱动动画里就行了,关键实现如下yF028资讯网——每日最新资讯28at.com

.con{  animation: check;  animation-timeline: scroll(x self);}@keyframes check{  from,to {    -webkit-mask: linear-gradient(to right, #fff calc(100% - 30px), transparent);  }}

效果如下yF028资讯网——每日最新资讯28at.com

还有一个问题,希望在没有超出的时候不显示后面的数量。yF028资讯网——每日最新资讯28at.com

关于这个,我本来是打算用样式查询来实现,但是遇到了一个问题,由于样式查询只能匹配到子元素,所以不得不将显示数量的标签放到.con容器内。但是这样一来,mask遮罩就会出现问题,就像这样yF028资讯网——每日最新资讯28at.com

遮罩层连同数量标签一起被裁剪了!yF028资讯网——每日最新资讯28at.com

于是又想出了另一种方案,这个在以前的布局中其实用到的更多,那就是负margin。yF028资讯网——每日最新资讯28at.com

实现很简单,给标签容器一个的负margin-right,这样,右边的数量就会被左边的标签盖住,比如yF028资讯网——每日最新资讯28at.com

.con{  margin-right: -20px;}

效果如下yF028资讯网——每日最新资讯28at.com

是不是已经被盖住一部分了?我们继续向左偏移yF028资讯网——每日最新资讯28at.com

.con{  margin-right: -50px;}

这样就完全看不到右边的数量了yF028资讯网——每日最新资讯28at.com

那么,如何在超出时显示数量呢?这里就体现出负margin的好处了,可以借助前一个元素来隐藏后一个元素,在这里,我们直接在前面的动画中还原margin就行了yF028资讯网——每日最新资讯28at.com

.con{  animation: check;  animation-timeline: scroll(x self);}@keyframes check{  from,to {    -webkit-mask: linear-gradient(to right, #fff calc(100% - 30px), transparent);    margin-right: 0;  }}

这样就完美实现了文章开头所示效果了yF028资讯网——每日最新资讯28at.com

你也可以访问以下链接来体验真实效果(Chrome115+)yF028资讯网——每日最新资讯28at.com

  • CSS auto tag num (juejin.cn)[2]
  • CSS auto tag num (codepen.io)[3]

五、总结一下

以上就是本文的全部内容了,不知道你学会了吗?下面总结一下实现重点:yF028资讯网——每日最新资讯28at.com

  1. 很多时候,CSS并没有直接的实现方式,需要“绕”点弯路
  2. CSS计数器可以实现数字累加
  3. CSS滚动驱动动画可以检测元素是否在可视范围之内
  4. CSS滚动驱动动画还能检测元素是否内容超出
  5. 计数累加器可以放在滚动驱动动画中,这样在动画触发时也就相当于计数器生效了,这样就能统计可视区的标签数量了
  6. 样式查询只能匹配到子元素,但是用子元素会受到mask遮罩的影响
  7. 负margin可以借助前一个元素来隐藏后一个元素

yF028资讯网——每日最新资讯28at.com

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-87492-0.html纯 CSS 实现标签自动显示超出数量

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: RabbitMQ如何保证消息可靠性?

下一篇: 如何在Ollama创建自定义模型?构建本地大模型

标签:
  • 热门焦点
Top
Baidu
map