今天有一位掘友問我一個問題:
文字不換行,超出容器,怎麼滾動顯示?
比如下圖中,有的列表項的文字短,有的文字長。
需求是:希望文字長的部分能通過動畫滾動顯示。
我的第一反應是用純 CSS 做不了。
但是後來冥思苦想一陣子,竟然做到了!
其中涉及了一些有趣 CSS 知識點,在這裡分享一下。
1. 如何讓文字溢位容器?
work-break 屬性是用來處理文字如何換行的,這裡使用了不太常用的值 keep-all,表示只能在半形空格或連字元處換行。因為文字里沒有這兩種特殊字元,因此文字溢位了。
2. 如何讓元素寬度隨內容而定?
指定了 width 值為 fit-content,它是 CSS3 新的屬性值,表示寬度與內容一致。除了 fit-content 之外,還有 max-content、 min-content 和 fill-available。具體含義如有不清楚的,請 google 之。3. 動起來?
這裡我們使用關鍵幀動畫,使其滾動起來先。關鍵幀定義如下:
@keyframes move {
0%{
transform: translateX(0px);
}
100%{
transform: translateX(-100%);
}
}
複製程式碼
具體效果是:
這裡可以看出,我們在第 2 步設定元素的寬度為文字自身寬度的原因是,我們動畫移動元素是相對於自身的寬度的。
目前效果還是比較粗糙,比如整體移動 100%,我們希望文字尾部與 div 容器內容盒右邊卡齊:
由於我們知道父元素的 width 值的(這裡是 100px),使用 calc() 就能輕鬆做到:
@keyframes move {
0%{
transform: translateX(0px);
}
100%{
transform: translateX(calc(-100% + 100px));
}
}
複製程式碼
同時再讓父元素隱藏溢位部分,效果如下:
4. 如何讓短文字不動?
總體上實現了滾動的效果,但是掘友的需求是,長文字滾動,短文字不動的。
說實話,我為這個需求苦惱了小半天。。。後來,直拍大腿:設定 p 的最小寬度呀!
5. 最後一步,優化動畫!
現在的效果,怎麼說呢,滾動得太讓人鬧心,可以讓動畫滾動開始和結束前,稍微停頓一會兒:
@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/…。
本文完。
謝謝閱讀!
???