CSS 滾屏效果,要比想象中的難

老姚發表於2019-03-29

今天有一位掘友問我一個問題:

文字不換行,超出容器,怎麼滾動顯示?

比如下圖中,有的列表項的文字短,有的文字長。

CSS 滾屏效果,要比想象中的難

需求是:希望文字長的部分能通過動畫滾動顯示

我的第一反應是用純 CSS 做不了。

但是後來冥思苦想一陣子,竟然做到了!

其中涉及了一些有趣 CSS 知識點,在這裡分享一下。

1. 如何讓文字溢位容器?

CSS 滾屏效果,要比想象中的難

work-break 屬性是用來處理文字如何換行的,這裡使用了不太常用的值 keep-all,表示只能在半形空格或連字元處換行。因為文字里沒有這兩種特殊字元,因此文字溢位了。

2. 如何讓元素寬度隨內容而定?

CSS 滾屏效果,要比想象中的難
指定了 width 值為 fit-content,它是 CSS3 新的屬性值,表示寬度與內容一致。除了 fit-content 之外,還有 max-content、 min-content 和 fill-available。具體含義如有不清楚的,請 google 之。

3. 動起來?

這裡我們使用關鍵幀動畫,使其滾動起來先。關鍵幀定義如下:

@keyframes move {
  0%{
    transform: translateX(0px);
  }
  100%{
    transform: translateX(-100%);
  }
}
複製程式碼

具體效果是:

CSS 滾屏效果,要比想象中的難

這裡可以看出,我們在第 2 步設定元素的寬度為文字自身寬度的原因是,我們動畫移動元素是相對於自身的寬度的。

目前效果還是比較粗糙,比如整體移動 100%,我們希望文字尾部與 div 容器內容盒右邊卡齊:

CSS 滾屏效果,要比想象中的難

由於我們知道父元素的 width 值的(這裡是 100px),使用 calc() 就能輕鬆做到:

@keyframes move {
  0%{
    transform: translateX(0px);
  }
  100%{
    transform: translateX(calc(-100% + 100px));
  }
}
複製程式碼

同時再讓父元素隱藏溢位部分,效果如下:

CSS 滾屏效果,要比想象中的難

4. 如何讓短文字不動?

總體上實現了滾動的效果,但是掘友的需求是,長文字滾動,短文字不動的。

CSS 滾屏效果,要比想象中的難
說實話,我為這個需求苦惱了小半天。。。

後來,直拍大腿:設定 p 的最小寬度呀!

CSS 滾屏效果,要比想象中的難

5. 最後一步,優化動畫!

現在的效果,怎麼說呢,滾動得太讓人鬧心,可以讓動畫滾動開始和結束前,稍微停頓一會兒:

@keyframes move {
  0%, 20%{
    transform: translateX(0px);
  }
  80%,100%{
    transform: translateX(calc(-100% + 100px));
  }
}
複製程式碼

前 20% 保持效果不變,後 20% 亦是如此:

CSS 滾屏效果,要比想象中的難

還有一個問題,這裡我們的動畫時間是 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;
複製程式碼

CSS 滾屏效果,要比想象中的難

最後,完整程式碼和完整效果,請看codepen.io/laoyao/pen/…


本文完。

謝謝閱讀!

???

相關文章