瞭解如何建立分割字母和文字動畫的基礎總覽。
在這篇文章中,我想和大家分享如何解決分割文字動畫的問題。 透過各種瀏覽器使用網路,享受極少、存取和順暢的互動體驗。 歡迎查看示範內容。
如果您喜歡看影片,請參考這篇文章的 YouTube 版本:
總覽
分割文字動畫非常驚人我們會稍微抓到 但確實有助於建構 取代。目標是逐步加入動畫。文字 動畫預設是建立在最上面的動畫分割文字動態效果可以 過度雜亂且可能造成乾擾,因此我們只操縱 HTML 假如使用者動作符合情境,則套用動態樣式。
以下是工作流程和結果的概要說明:
- 準備減少動作條件 CSS 和 JS 的變數。
- 準備分割文字公用程式: JavaScript。
- 在網頁上自動化調度管理條件和公用程式 載入。
- 編寫 CSS 轉場效果和動畫 代表字母和字詞 (雷達部分!)。
以下為我們想要的條件式結果預覽:
![Chrome 開發人員工具開啟「Elements」面板,並將動態效果設為「reduce」且 h1 顯示為未分割](https://web.developers.google.cn/static/articles/building/split-text-animations/image/screenshot-the-chrome-de-65fd5b490f405.png?authuser=19&hl=zh-tw)
如果使用者偏好減少動態效果,我們會單獨保留 HTML 文件,不做任何 如果動作沒有問題,我們就會將其切割成多個片段。請參考 JavaScript 將文字拆成一個字母,點選即可預覽 HTML 版本
![Chrome 開發人員工具開啟「Elements」面板,並將動態效果設為「reduce」且 h1 顯示為未分割](https://web.developers.google.cn/static/articles/building/split-text-animations/image/screenshot-the-chrome-de-fd950f1664ff6.png?authuser=19&hl=zh-tw)
準備動作條件式
便利可用的 @media
(prefers-reduced-motion: reduce)
媒體查詢會從 CSS 及
在這個專案中使用 JavaScript此媒體查詢是我們的主要條件
決定是否要分割文字CSS 媒體查詢將會用來暫緩
轉換和動畫,而 JavaScript 媒體查詢則可用來
並保留 HTML 操作
準備 CSS 條件式
我使用 PostCSS 啟用第 5 級媒體查詢的語法,我可以在當中儲存 將媒體查詢布林值轉換為變數:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
準備 JS 條件式
在 JavaScript 中,瀏覽器可以用來檢查媒體查詢, 破壞 ,從媒體查詢檢查中擷取並重新命名布林值結果:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
以便我們測試 motionOK
的內容,只有在使用者沒有
已提出減少動作的要求
if (motionOK) {
// document split manipulations
}
我可以使用 PostCSS 啟用 @nest
語法,檢查相同的值:
巢狀結構草稿 1。這樣一來
會儲存動畫的所有邏輯,以及動畫的樣式規定
。
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
有了 PostCSS 自訂屬性和 JavaScript 布林值,我們就可以 有條件地升級效果這就說明瞭下一節 拆解用來將字串轉換為元素的 JavaScript。
分割文字
CSS 或 JS 不能分別使用文字字母、字詞和行等動畫。 為實現效果,我們需要有方塊。如果要為每個字母建立動畫 每個字母都必須是元素如果要為每個字詞產生動畫 都必須是元素
- 建立 JavaScript 公用程式函式,將字串分割成元素
- 調度管理這些公用程式的用法
分割字母公用程式函式
有一個有趣的起點是函式,這個函式會使用函式擷取字串並傳回每個 陣列中的字母。
export const byLetter = text =>
[...text].map(span)
分散 語法讓工作快速簡單
分割字詞公用程式函式
與分割字母類似,此函式會採用字串並傳回每個字詞 陣列。
export const byWord = text =>
text.split(' ').map(span)
split()
敬上
方法,以便我們指定要切入的字元。
我傳遞了空白處,表示每個字詞之間有所分割。
設計方塊實用性
效果需要每個字母組成方塊,而在函式中,我們可以看到
map()
敬上
是以 span()
函式呼叫以下是 span()
函式。
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
請務必注意,系統會使用名為 --index
的自訂屬性設定
陣列位置。使用字母動畫方塊固然很好
原本為 CSS 供應商提供的索引,這項增加似乎沒什麼影響,
這項重大影響上最值得注意的是
交錯。
我們將能使用 --index
做為交錯式動畫的方式。
快看,
公用事業結論
完成中的 splitting.js
模組:
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
export const byLetter = text =>
[...text].map(span)
export const byWord = text =>
text.split(' ').map(span)
接著要匯入並使用這些 byLetter()
和 byWord()
函式。
分割自動化調度管理
分割公用程式可供使用後,如果將所有值放在一起,代表:
- 找出要分割的元素
- 分割文字並使用 HTML 取代文字
CSS 隨即會接手,為元素 / 方塊建立動畫。
發現項目元素
我選擇使用屬性和值來儲存想要的資訊
以及如何分割文字我喜歡導入這些宣告式選項
轉換為 HTML。JavaScript 會使用 split-by
屬性來尋找
元素,並為字母或字詞建立方塊。屬性
系統會使用 CSS 中的 letter-animation
或 word-animation
來指定元素
並套用變形和動畫
以下 HTML 範例說明這兩個屬性:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
從 JavaScript 尋找元素
我使用 CSS 選取器語法來收集是否有屬性清單 以下元素:
const splitTargets = document.querySelectorAll('[split-by]')
從 CSS 尋找元素
我也會在 CSS 中使用屬性出現工具,讓所有字母動畫都能呈現 相同的基本樣式稍後我們會使用屬性值來加入更具體的 即可套用各種樣式
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
正在分割文字
我們會針對 JavaScript 中找到的每個分割目標,分別拆分文字
並將每個字串對應到 <span>
。我們可以
使用我們建立的方塊取代元素文字:
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter') {
nodes = byLetter(node.innerText)
}
else if (type === 'word') {
nodes = byWord(node.innerText)
}
if (nodes) {
node.firstChild.replaceWith(...nodes)
}
})
協調結論
完成的 index.js
:
import {byLetter, byWord} from './splitting.js'
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
if (motionOK) {
const splitTargets = document.querySelectorAll('[split-by]')
splitTargets.forEach(node => {
const type = node.getAttribute('split-by')
let nodes = null
if (type === 'letter')
nodes = byLetter(node.innerText)
else if (type === 'word')
nodes = byWord(node.innerText)
if (nodes)
node.firstChild.replaceWith(...nodes)
})
}
JavaScript 可能變成以下英文:
- 匯入一些輔助公用程式函式。
- 檢查該使用者是否能使用動態功能;如果未執行任何動作,請檢查此動作是否正常運作。
- 對要分割的每個元素。
- 請依據想要的分割方式加以分割。
- 將文字替換為元素。
分割動畫和轉場效果
上述的分割文件操控功能 讓 可能呈現的動畫和效果以下介紹 ,瞭解如何拓展您的分潤。
現在就來展現你如何做到這一點吧!我會分享 4 種 CSS 驅動動畫 轉場效果🤓
分割字母
我認為下列 CSS 是分割字母效果的基礎
很有幫助。我在動作媒體查詢後面加上所有轉場效果和動畫
然後為每個新的子項字母 span
加上一個顯示屬性,再加上元素樣式
如何使用空格:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
空白空格樣式十分重要,確保跨距只是空格 不要由版面配置引擎收合現在來談談有狀態的有趣內容。
轉換分割字母範例
這個範例使用 CSS 轉換為分割文字效果。有了轉場效果 而引擎所需的狀態,而我選擇了三種狀態: 懸停、將遊標懸停在句子上或將遊標懸停在字母上。
當使用者將滑鼠遊標懸停在句子 (又稱容器) 上時,我會縮減所有字詞 就是把他們推向別處接著,當使用者將滑鼠遊標懸停在 。
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
為分割字母加上動畫效果範例
這個範例使用預先定義的 @keyframe
動畫,為每個元素建立無限動畫
,並利用內嵌自訂屬性索引建立片段
效果。
@media (--motionOK) {
[letter-animation="breath"] > span {
animation:
breath 1200ms ease
calc(var(--index) * 100 * 1ms)
infinite alternate;
}
}
@keyframes breath {
from {
animation-timing-function: ease-out;
}
to {
transform: translateY(-5px) scale(1.25);
text-shadow: 0 0 25px var(--glow-color);
animation-timing-function: ease-in-out;
}
}
分割字詞
Flexbox 就如同這些範例的容器類型,很不錯
使用 ch
單位做為健康差距長度。
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
轉場分割字詞範例
在這個轉場範例中,我再次使用懸停功能。因為這個效果一開始會隱藏 內容懸停後,我確定只套用了互動和樣式 表示裝置具備懸停功能
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
為分割字詞動畫範例
在這個動畫範例中,我再次使用 CSS @keyframes
建立分段式
一般文字段落的無限動畫。
[word-animation="trampoline"] > span {
display: inline-block;
transform: translateY(100%);
animation:
trampoline 3s ease
calc(var(--index) * 150 * 1ms)
infinite alternate;
}
@keyframes trampoline {
0% {
transform: translateY(100%);
animation-timing-function: ease-out;
}
50% {
transform: translateY(0);
animation-timing-function: ease-in;
}
}
結論
現在你知道該怎麼做了,你會怎麼做?!🙂
讓我們來體驗多元的方法,瞭解透過網路建立內容的所有方式。 建立 Codepen 或主持自己的示範,並透過 Twitter 推文給我,我會將它新增到 下方的社群重混作品部分。
來源
更多示範和靈感
社群重混作品
- CodeSandbox 上的 gnehcwu 提供
<text-hover>
網頁元件