今天有一位掘友问我一个问题:javascript
文字不换行,超出容器,怎么滚动显示? css
好比下图中,有的列表项的文字短,有的文字长。java
需求是:但愿文字长的部分能经过动画滚动显示。markdown
个人第一反应是用纯 CSS 作不了。oop
可是后来左思右想一阵子,居然作到了!优化
其中涉及了一些有趣 CSS 知识点,在这里分享一下。动画
work-break 属性是用来处理文字如何换行的,这里使用了不太经常使用的值 keep-all,表示只能在半角空格或连字符处换行。由于文本里没有这两种特殊字符,所以文本溢出了。google
这里咱们使用关键帧动画,使其滚动起来先。关键帧定义以下:spa
@keyframes move { 0%{ transform: translateX(0px); } 100%{ transform: translateX(-100%); } } 复制代码
具体效果是:code
这里能够看出,咱们在第 2 步设置元素的宽度为文字自身宽度的缘由是,咱们动画移动元素是相对于自身的宽度的。
目前效果仍是比较粗糙,好比总体移动 100%,咱们但愿文字尾部与 div 容器内容盒右边卡齐:
因为咱们知道父元素的 width 值的(这里是 100px),使用 calc() 就能轻松作到:
@keyframes move { 0%{ transform: translateX(0px); } 100%{ transform: translateX(calc(-100% + 100px)); } } 复制代码
同时再让父元素隐藏溢出部分,效果以下:
整体上实现了滚动的效果,可是掘友的需求是,长文字滚动,短文字不动的。
后来,直拍大腿:设置 p 的最小宽度呀!
如今的效果,怎么说呢,滚动得太让人闹心,可让动画滚动开始和结束前,稍微停顿一下子:
@keyframes move { 0%, 20%{ transform: translateX(0px); } 80%,100%{ transform: translateX(calc(-100% + 100px)); } } 复制代码
前 20% 保持效果不变,后 20% 亦是如此:
还有一个问题,这里咱们的动画时间是 3s,咱们能够根据其文字长度来设置时间。即,更长的文字须要更长的时间。
但此处,我不知道用 CSS 怎么办,尝试了几回,最终仍是放弃了,使用了一小段 JS。
[...document.querySelectorAll('p')].forEach(p => { p.style.setProperty('--duration', p.offsetWidth / 100 + 's'); }) 复制代码
其中 --duration 是 CSS 变量(不熟悉的同窗请 google 之),p 标签的 animation 属性也须要相应变为:
animation: move var(--duration) linear infinite; 复制代码
最后,完整代码和完整效果,请看codepen.io/laoyao/pen/…。
谢谢阅读!
🙏🙏🙏