Ringkasan dasar tentang cara membuat animasi huruf dan kata yang terpisah.
Dalam postingan ini, saya ingin membagikan pemikiran tentang cara menyelesaikan animasi dan interaksi teks terpisah untuk web yang minimal, dapat diakses, dan berfungsi di seluruh browser. Coba demo.
Jika Anda lebih suka menonton video, berikut versi YouTube dari postingan ini:
Ringkasan
Animasi teks terpisah bisa sangat menarik. Kita hanya akan membahas sedikit potensi animasi dalam postingan ini, tetapi hal ini memberikan dasar untuk membangunnya. Tujuannya adalah untuk menganimasikan secara progresif. Teks harus dapat dibaca secara default, dengan animasi yang dibuat di atasnya. Efek gerakan teks terpisah dapat menjadi berlebihan dan berpotensi mengganggu, jadi kita hanya akan memanipulasi HTML, atau menerapkan gaya gerakan jika pengguna setuju dengan gerakan.
Berikut ringkasan umum alur kerja dan hasilnya:
- Siapkan variabel bersyarat gerakan yang dikurangi untuk CSS dan JS.
- Menyiapkan utilitas teks terpisah di JavaScript.
- Atur kondisi dan utilitas pada pemuatan halaman.
- Tulis transisi dan animasi CSS untuk huruf dan kata (bagian yang keren!).
Berikut pratinjau hasil bersyarat yang akan kita buat:

Jika pengguna lebih memilih gerakan yang dikurangi, kita tidak mengubah dokumen HTML dan tidak melakukan animasi. Jika gerakan sudah sesuai, kita lanjutkan dengan memotongnya menjadi beberapa bagian. Berikut pratinjau HTML setelah JavaScript memisahkan teks berdasarkan huruf.

Menyiapkan kondisi gerakan
Kueri media @media
(prefers-reduced-motion: reduce)
yang tersedia dan mudah digunakan akan digunakan dari CSS dan
JavaScript dalam project ini. Kueri media ini adalah kondisi utama kami untuk
memutuskan apakah akan memisahkan teks atau tidak. Kueri media CSS akan digunakan untuk menahan transisi dan animasi, sedangkan kueri media JavaScript akan digunakan untuk menahan manipulasi HTML.
Menyiapkan kondisi CSS
Saya menggunakan PostCSS untuk mengaktifkan sintaks Media Queries Level 5, tempat saya dapat menyimpan boolean kueri media ke dalam variabel:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Menyiapkan kondisi JS
Di JavaScript, browser menyediakan cara untuk memeriksa kueri media. Saya menggunakan destructuring untuk mengekstrak dan mengganti nama hasil boolean dari pemeriksaan kueri media:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Kemudian, saya dapat menguji motionOK
, dan hanya mengubah dokumen jika pengguna belum
meminta untuk mengurangi gerakan.
if (motionOK) {
// document split manipulations
}
Saya dapat memeriksa nilai yang sama menggunakan PostCSS untuk mengaktifkan sintaksis @nest
dari
Nesting Draf 1. Dengan begitu, saya dapat
menyimpan semua logika tentang animasi dan persyaratan gaya untuk
induk dan turunan, di satu tempat:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Dengan properti kustom PostCSS dan boolean JavaScript, kita siap untuk mengupgrade efek secara kondisional. Hal ini akan membawa kita ke bagian berikutnya tempat saya menguraikan JavaScript untuk mengubah string menjadi elemen.
Memisahkan Teks
Huruf, kata, baris, dll., teks tidak dapat dianimasikan satu per satu dengan CSS atau JS. Untuk mendapatkan efek tersebut, kita memerlukan kotak. Jika kita ingin menganimasikan setiap huruf, maka setiap huruf harus menjadi elemen. Jika kita ingin menganimasikan setiap kata, maka setiap kata harus menjadi elemen.
- Membuat fungsi utilitas JavaScript untuk memisahkan string menjadi elemen
- Mengatur penggunaan utilitas ini
Fungsi utilitas pemisahan huruf
Tempat yang menyenangkan untuk memulai adalah dengan fungsi yang mengambil string dan menampilkan setiap huruf dalam array.
export const byLetter = text =>
[...text].map(span)
Sintaksis spread dari ES6 sangat membantu mempercepat tugas tersebut.
Fungsi utilitas pemisahan kata
Mirip dengan memisahkan huruf, fungsi ini mengambil string dan menampilkan setiap kata dalam array.
export const byWord = text =>
text.split(' ').map(span)
Metode
split()
pada string JavaScript memungkinkan kita menentukan karakter mana yang akan dipotong.
Saya melewati ruang kosong, yang menunjukkan pemisahan antar-kata.
Fungsi utilitas kotak pembuatan
Efeknya memerlukan kotak untuk setiap huruf, dan kita melihat dalam fungsi tersebut, bahwa
map()
dipanggil dengan fungsi span()
. Berikut adalah fungsi span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Penting untuk diperhatikan bahwa properti kustom bernama --index
sedang disetel dengan
posisi array. Memiliki kotak untuk animasi huruf sangat bagus, tetapi memiliki indeks untuk digunakan di CSS adalah tambahan yang tampaknya kecil dengan dampak yang besar.
Dampak besar yang paling terlihat adalah
mengejutkan.
Kita dapat menggunakan --index
sebagai cara untuk mengimbangi animasi agar terlihat
bertahap.
Kesimpulan utilitas
Modul splitting.js
dalam penyelesaian:
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)
Selanjutnya adalah mengimpor dan menggunakan fungsi byLetter()
dan byWord()
ini.
Orkestrasi pemisahan
Dengan utilitas pemisahan yang siap digunakan, menyatukan semuanya berarti:
- Menemukan elemen yang akan dibagi
- Memisahkan dan mengganti teks dengan HTML
Setelah itu, CSS akan mengambil alih dan menganimasikan elemen / kotak.
Menemukan Elemen
Saya memilih untuk menggunakan atribut dan nilai untuk menyimpan informasi tentang animasi yang diinginkan dan cara memisahkan teks. Saya suka menempatkan opsi deklaratif ini ke dalam HTML. Atribut split-by
digunakan dari JavaScript, untuk menemukan
elemen dan membuat kotak untuk huruf atau kata. Atribut
letter-animation
atau word-animation
digunakan dari CSS, untuk menargetkan elemen
turunan dan menerapkan transformasi serta animasi.
Berikut adalah contoh HTML yang menunjukkan kedua atribut tersebut:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Menemukan elemen dari JavaScript
Saya menggunakan sintaksis pemilih CSS untuk kehadiran atribut guna mengumpulkan daftar elemen yang ingin memisahkan teksnya:
const splitTargets = document.querySelectorAll('[split-by]')
Menemukan elemen dari CSS
Saya juga menggunakan pemilih kehadiran atribut di CSS untuk memberikan gaya dasar yang sama pada semua animasi huruf. Nanti, kita akan menggunakan nilai atribut untuk menambahkan gaya yang lebih spesifik guna mencapai efek.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Memisahkan teks di tempat
Untuk setiap target pemisahan yang kami temukan di JavaScript, kami akan memisahkan teksnya berdasarkan nilai atribut dan memetakan setiap string ke <span>
. Kemudian, kita dapat mengganti teks elemen dengan kotak yang kita buat:
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)
}
})
Kesimpulan orkestrasi
index.js
setelah selesai:
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 dapat dibaca dalam bahasa Inggris berikut:
- Impor beberapa fungsi utilitas pembantu.
- Periksa apakah gerakan sudah sesuai untuk pengguna ini, jika tidak, jangan lakukan apa pun.
- Untuk setiap elemen yang ingin dibagi.
- Pisahkan berdasarkan cara yang mereka inginkan.
- Mengganti teks dengan elemen.
Memisahkan animasi dan transisi
Manipulasi dokumen pemisahan di atas baru saja membuka banyak potensi animasi dan efek dengan CSS atau JavaScript. Ada beberapa link di bagian bawah artikel ini untuk membantu menginspirasi potensi pemisahan Anda.
Saatnya menunjukkan apa yang dapat Anda lakukan dengan fitur ini. Saya akan membagikan 4 animasi dan transisi yang didorong CSS. 🤓
Huruf terpisah
Sebagai dasar untuk efek huruf terpisah, saya menemukan CSS berikut berguna. Saya menempatkan semua transisi dan animasi di belakang kueri media gerakan, lalu memberikan properti tampilan dan gaya untuk setiap huruf turunan baru span
untuk menentukan apa yang harus dilakukan dengan ruang kosong:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Gaya ruang putih penting agar rentang yang hanya berupa spasi, tidak diciutkan oleh mesin tata letak. Sekarang kita masuk ke bagian yang menyenangkan dan stateful.
Contoh huruf terpisah transisi
Contoh ini menggunakan transisi CSS untuk efek teks terpisah. Dengan transisi, kita memerlukan status agar mesin dapat membuat animasi di antaranya, dan saya memilih tiga status: tidak ada kursor, kursor berada di dalam kalimat, kursor berada di huruf.
Saat pengguna mengarahkan kursor ke kalimat, alias penampung, saya akan mengecilkan semua elemen turunan seolah-olah pengguna mendorongnya lebih jauh. Kemudian, saat pengguna mengarahkan kursor ke huruf, saya akan memajukannya.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Contoh huruf terpisah yang dianimasikan
Contoh ini menggunakan animasi @keyframe
yang telah ditentukan sebelumnya untuk menganimasikan setiap huruf tanpa batas, dan memanfaatkan indeks properti kustom inline untuk membuat efek berjenjang.
@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;
}
}
Memisahkan kata
Flexbox berfungsi sebagai jenis penampung bagi saya di sini dalam contoh ini, dengan memanfaatkan unit ch
sebagai panjang jarak yang tepat.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Contoh kata pemisahan transisi
Dalam contoh transisi ini, saya menggunakan pengarahan kursor lagi. Karena efek awalnya menyembunyikan konten hingga kursor diarahkan, saya memastikan bahwa interaksi dan gaya hanya diterapkan jika perangkat memiliki kemampuan untuk mengarahkan kursor.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Contoh kata yang dipisah dan dianimasikan
Dalam contoh animasi ini, saya menggunakan @keyframes
CSS lagi untuk membuat animasi tak terbatas yang bertahap pada paragraf teks biasa.
[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;
}
}
Kesimpulan
Sekarang setelah Anda tahu cara saya melakukannya, bagaimana Anda?! 🙂
Mari kita diversifikasi pendekatan kita dan pelajari semua cara untuk membangun di web. Buat Codepen atau hosting demo Anda sendiri, kirimkan tweet kepada saya, dan saya akan menambahkannya ke bagian Remix komunitas di bawah.
Sumber
Lebih banyak demo dan inspirasi
Remix komunitas
- Komponen web
<text-hover>
oleh gnehcwu di CodeSandbox