Bölünmüş harf ve kelime animasyonları oluşturma hakkında temel bilgiler.
Bu yayında, web için bölünmüş metin animasyonlarını ve etkileşimlerini çözmenin en az çaba gerektiren, erişilebilir ve tarayıcılar arasında çalışan yolları hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.
Video tercih ediyorsanız bu yayının YouTube versiyonunu aşağıda bulabilirsiniz:
Genel Bakış
Bölünmüş metin animasyonları harika olabilir. Bu yayında animasyon potansiyelinin sadece küçük bir kısmına değineceğiz ancak bu bilgiler, üzerine inşa edebileceğiniz bir temel oluşturacaktır. Hedef, animasyonu kademeli olarak oluşturmaktır. Metin, varsayılan olarak okunabilir olmalı ve animasyon bunun üzerine kurulmalıdır. Metin hareket efektlerini bölme işlemi, abartılı ve rahatsız edici olabilir. Bu nedenle yalnızca HTML'yi değiştiririz veya kullanıcı hareketten rahatsız olmuyorsa hareket stilleri uygularız.
İş akışına ve sonuçlara genel bir bakış:
- CSS ve JS için hazırlanmış hareket koşullu değişkenlerini azaltın.
- JavaScript'te hazırlama, metin yardımcı programlarını bölme.
- Sayfa yüklemesinde koşulları ve yardımcı programları düzenleyin.
- Harfler ve kelimeler için CSS geçişleri ve animasyonları yazın (en eğlenceli kısım!).
Hedeflediğimiz koşullu sonuçların önizlemesini aşağıda görebilirsiniz:

Kullanıcı, hareketi azaltmayı tercih ediyorsa HTML belgesini olduğu gibi bırakırız ve animasyon eklemeyiz. Hareket iyiyse videoyu parçalara ayırırız. JavaScript, metni harflere ayırdıktan sonraki HTML'nin önizlemesini aşağıda görebilirsiniz.

Hareket koşullarını hazırlama
Bu projede CSS ve JavaScript'ten kolayca kullanılabilen @media
(prefers-reduced-motion: reduce)
medya sorgusu kullanılacak. Bu medya sorgusu, metni bölüp bölmeyeceğimize karar verirken kullandığımız birincil koşuldur. CSS medya sorgusu, geçişleri ve animasyonları engellemek için kullanılırken JavaScript medya sorgusu, HTML manipülasyonunu engellemek için kullanılır.
CSS koşulunu hazırlama
Media Queries Level 5'in söz dizimini etkinleştirmek için PostCSS'yi kullandım. Burada bir medya sorgusu boole'unu değişkende saklayabilirim:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
JS koşulunu hazırlama
JavaScript'te tarayıcı, medya sorgularını kontrol etmenin bir yolunu sunar. Medya sorgusu kontrolünden Boole sonucunu ayıklamak ve yeniden adlandırmak için yapı bozma kullandım:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Ardından motionOK
için test yapabilir ve yalnızca kullanıcı hareket azaltma isteğinde bulunmadıysa dokümanı değiştirebilirim.
if (motionOK) {
// document split manipulations
}
PostCSS'yi kullanarak Nesting Draft 1'deki @nest
söz dizimini etkinleştirerek aynı değeri kontrol edebilirim. Bu sayede, animasyonla ilgili tüm mantığı ve stil gereksinimlerini üst öğe ve alt öğeler için tek bir yerde saklayabilirim:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
PostCSS özel özelliği ve bir JavaScript boole'u ile efekti koşullu olarak yükseltmeye hazırız. Bu da bizi, dizeleri öğelere dönüştürmek için JavaScript'i ayrıntılı olarak açıkladığım bir sonraki bölüme götürüyor.
Metni Bölme
Metin harfleri, kelimeleri, satırları vb. CSS veya JS ile tek tek animasyonlu hale getirilemez. Bu efekti elde etmek için kutulara ihtiyacımız var. Her harfi ayrı ayrı canlandırmak istiyorsak her harf bir öğe olmalıdır. Her kelimeyi canlandırmak istiyorsak her kelime bir öğe olmalıdır.
- Dizeleri öğelere bölmek için JavaScript yardımcı işlevleri oluşturma
- Bu yardımcı programların kullanımını düzenleme
Harfleri bölme yardımcı işlevi
Başlamak için eğlenceli bir yer, bir dize alan ve her harfi bir dizide döndüren bir işlevdir.
export const byLetter = text =>
[...text].map(span)
ES6'daki spread söz dizimi, bu görevin hızlı bir şekilde tamamlanmasına gerçekten yardımcı oldu.
Kelimeleri bölme yardımcı işlevi
Bu işlev, harfleri bölmeye benzer şekilde bir dize alır ve her kelimeyi bir dizide döndürür.
export const byWord = text =>
text.split(' ').map(span)
JavaScript dizelerindeki split()
yöntemi, hangi karakterlerin kesileceğini belirtmemize olanak tanır.
Kelimeler arasında boşluk olduğunu belirten boş bir alan geçtim.
Kutuları hizmet işlevi haline getirme
Efekt için her harf için kutu gerekir ve bu işlevlerde map()
öğesinin span()
işleviyle çağrıldığını görürüz. span()
işlevi aşağıda verilmiştir.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Dizi konumuyla --index
adlı bir özel özelliğin ayarlandığını unutmamak önemlidir. Harf animasyonları için kutuların olması harika bir özellik. Ancak CSS'de kullanılacak bir dizinin olması, küçük gibi görünse de büyük bir etki yaratıyor.
Bu büyük etki içinde en dikkat çekici olanı şaşırtıcı.
--index
, animasyonları kademeli bir görünüm için kaydırmak amacıyla kullanılabilir.
Yardımcı programlar sonucu
Tamamlanan splitting.js
modülü:
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)
Ardından, bu byLetter()
ve byWord()
işlevlerini içe aktarıp kullanma gelir.
Bölünmüş düzenleme
Bölme yardımcı programları kullanıma hazır olduğunda, tüm bunları bir araya getirmek için:
- Hangi öğelerin bölüneceğini bulma
- Metinleri bölme ve HTML ile değiştirme
Ardından CSS devreye girer ve öğelere / kutulara animasyon uygular.
Öğeleri bulma
İstediğim animasyon ve metnin nasıl bölüneceğiyle ilgili bilgileri depolamak için özellikleri ve değerleri kullanmayı tercih ettim. Bu bildirimsel seçenekleri HTML'ye eklemeyi beğendim. split-by
özelliği, JavaScript'ten kullanılarak öğeler bulunur ve harfler veya kelimeler için kutular oluşturulur. Özellik
letter-animation
veya word-animation
, CSS'den öğe
alt öğelerini hedeflemek ve dönüştürmeler ile animasyonlar uygulamak için kullanılır.
İki özelliği gösteren bir HTML örneğini aşağıda bulabilirsiniz:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
JavaScript'ten öğe bulma
Metinlerinin bölünmesini isteyen öğelerin listesini toplamak için özellik varlığıyla ilgili CSS seçici söz dizimini kullandım:
const splitTargets = document.querySelectorAll('[split-by]')
CSS'den öğe bulma
Ayrıca, tüm harf animasyonlarına aynı temel stilleri vermek için CSS'de özellik varlığı seçicisini kullandım. Daha sonra, bir efekt elde etmek için daha spesifik stiller eklemek üzere özellik değerini kullanacağız.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Metni yerinde bölme
JavaScript'te bulduğumuz her bölünmüş hedef için metinlerini özelliğin değerine göre böler ve her dizeyi bir <span>
ile eşleriz. Ardından, öğenin metnini oluşturduğumuz kutularla değiştirebiliriz:
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)
}
})
Orkestrasyon sonucu
index.js
tamamlandı:
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 aşağıdaki İngilizce metinde okunabilir:
- Bazı yardımcı program işlevlerini içe aktarın.
- Bu kullanıcı için hareketin uygun olup olmadığını kontrol edin. Uygun değilse herhangi bir işlem yapmayın.
- Bölünmek istenen her öğe için.
- Bunları, nasıl bölünmek istediklerine göre bölün.
- Metni öğelerle değiştirin.
Animasyonları ve geçişleri bölme
Yukarıdaki belge bölme işlemi, CSS veya JavaScript ile çok sayıda potansiyel animasyon ve efektin kilidini açtı. Bu makalenin en altında, bölme potansiyelinizi artırmanıza yardımcı olacak birkaç bağlantı bulabilirsiniz.
Bu araçla neler yapabileceğinizi gösterme zamanı! CSS ile çalışan 4 animasyon ve geçiş paylaşacağım. 🤓
Bölünmüş harfler
Bölünmüş harf efektlerinin temeli olarak aşağıdaki CSS'nin faydalı olduğunu gördüm. Tüm geçişleri ve animasyonları hareket medya sorgusunun arkasına yerleştirip her yeni alt harfe span
bir görüntüleme özelliği ve boşluklarla ne yapılacağına dair bir stil veriyorum:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Yalnızca boşluk olan aralıkların düzen motoru tarafından daraltılmaması için boşluk stili önemlidir. Şimdi de durum bilgisi içeren eğlenceli konulara geçelim.
Geçişte bölünmüş harfler örneği
Bu örnekte, bölünmüş metin efektine CSS geçişleri uygulanmaktadır. Geçişlerde, motorun animasyon oluşturmak için kullanacağı durumlar gerekir. Ben üç durum seçtim: fareyle üzerine gelmeme, fareyle cümle üzerinde gezinme ve fareyle harf üzerinde gezinme.
Kullanıcı, kapsayıcı olarak da bilinen cümlenin üzerine geldiğinde, kullanıcı çocukları daha da itmiş gibi tüm çocukları küçültüyorum. Ardından, kullanıcı bir harterin üzerine geldiğinde onu öne çıkarıyorum.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Bölünmüş harflere animasyon ekleme örneği
Bu örnekte, her harfi sonsuza kadar animasyonlu hale getirmek için önceden tanımlanmış bir @keyframe
animasyonu kullanılmakta ve kademeli bir efekt oluşturmak için satır içi özel özellik dizininden yararlanılmaktadır.
@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;
}
}
Kelimeleri bölme
Flexbox, bu örneklerde kapsayıcı türü olarak işe yaradı ve ch
birimini sağlıklı bir boşluk uzunluğu olarak güzel bir şekilde kullandı.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Geçişte bölünmüş kelimeler örneği
Bu geçiş örneğinde tekrar fareyle üzerine gelme özelliğini kullanıyorum. Efekt, fareyle üzerine gelene kadar içeriği gizlediğinden etkileşim ve stillerin yalnızca cihazda fareyle üzerine gelme özelliği varsa uygulandığından emin oldum.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Bölünmüş kelimelere animasyon ekleme örneği
Bu animasyon örneğinde, normal bir metin paragrafında kademeli sonsuz animasyon oluşturmak için tekrar CSS @keyframes
kullanıyorum.
[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;
}
}
Sonuç
Benim nasıl yaptığımı öğrendiğinize göre, siz nasıl yapardınız? 🙂
Yaklaşımlarımızı çeşitlendirelim ve web'de içerik oluşturmanın tüm yollarını öğrenelim. Codepen oluşturun veya kendi demoyu barındırın, bunu içeren bir tweet ile bana ulaşın. Ben de demoyu aşağıdaki Topluluk remiksleri bölümüne ekleyeyim.
Kaynak
Daha fazla demo ve ilham kaynağı
Topluluk remiksleri
<text-hover>
CodeSandbox'ta gnehcwu tarafından oluşturulan web bileşeni