Bölünmüş harf ve kelime animasyonlarının nasıl oluşturulacağına dair temel bir genel bakış.
Bu yayında, web'de bölünmüş metin animasyonlarını ve etkileşimlerini minimum düzeyde, erişilebilir ve tarayıcılar arasında çalışan şekilde çözme yolları hakkındaki düşüncelerimi paylaşmak istiyorum. Demoyu deneyin.
Video kullanmayı tercih ederseniz bu gönderinin YouTube versiyonunu kullanabilirsiniz:
Genel Bakış
Bölünmüş metin animasyonları şaşırtıcı olabilir. Bu yayında, animasyon potansiyelinin sadece küçük bir kısmını ele alacağız. Ancak bu, üzerine inşa edebileceğiniz bir temel sağlar. Amaç, aşamalı olarak animasyon oluşturmaktır. Metin, animasyon en üst kısma yerleştirilmiş şekilde varsayılan olarak okunabilmelidir. Bölünmüş metin hareket efektleri abartılı ve potansiyel olarak rahatsız edici olabilir. Bu nedenle, yalnızca HTML'yi değiştiririz veya kullanıcı hareketi kabul ediyorsa hareket stilleri uygularız.
Aşağıda iş akışına ve sonuçlara ilişkin genel bir bakış yer almaktadır:
- CSS ve JS için azaltılmış hareket koşullu değişkenleri hazırlayın.
- JavaScript'te bölünmüş metin yardımcı programlarını hazırlayın.
- Sayfa yüklenirken koşullu ifadeleri ve yardımcı programları düzenleyin.
- Harfler ve kelimeler için CSS geçişleri ve animasyonları yazın (en heyecan verici kısım budur).
Hedeflediğimiz koşullu sonuçların önizlemesini aşağıda görebilirsiniz:
Bir kullanıcı daha az hareketi tercih ederse, HTML belgesini olduğu gibi bırakırız ve animasyon yapmayız. Hareket iyiyse videoyu parçalara ayırırız. JavaScript metni harfe göre böldükten sonra HTML'nin önizlemesi aşağıda verilmiştir.
Hareket koşullarını hazırlama
Kullanılabilir @media
(prefers-reduced-motion: reduce)
medya sorgusu, bu projede CSS ve JavaScript'ten kullanılacaktır. Bu medya sorgusu, metni bölmeye 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'de yapılan değişiklikleri engellemek için kullanılır.
CSS koşullu ifadesi hazırlama
Bir medya sorgusu boole değerini bir değişkende saklayabileceğim Medya Sorguları 5. Seviye söz dizimini etkinleştirmek için PostCSS'i kullandım:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
JS koşullarını hazırlama
JavaScript'te tarayıcı, medya sorgularını kontrol etmenin bir yolunu sağlar. Medya sorgusu kontrolünden elde edilen Boole sonucunu ayıklayıp yeniden adlandırmak için yapı bozma özelliğini kullandım:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Ardından motionOK
için test yapabilir ve yalnızca kullanıcı hareketi azaltma isteğinde bulunmadıysa dokümanı değiştirebilirim.
if (motionOK) {
// document split manipulations
}
İç İçe Sarma Taslağı 1'den @nest
söz dizimini etkinleştirmek için PostCSS'yi kullanarak aynı değeri kontrol edebilirim. Bu sayede, animasyonla ilgili tüm mantığı ve ana öğe ile alt öğeler için stil şartlarını tek bir yerde saklayabilirim:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
PostCSS özel mülkü ve JavaScript doğru/yanlış değeri sayesinde efekti koşullu olarak yükseltmeye hazırız. Böylece, dizeleri öğelere dönüştürmek için JavaScript'i anlatacağım bir sonraki bölüme geçiyoruz.
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 bir harfi canlandırmak istiyorsak, her harfin bir öğe olması gerekir. Her bir kelimeyi canlandırmak istiyorsanız her kelimenin bir öğe olması gerekir.
- Dizeleri öğelere bölme için JavaScript yardımcı işlevleri oluşturma
- Bu yardımcı programların kullanımını koordine etme
Harfleri bölme yardımcı programı işlevi
Başlamak için eğlenceli bir işlev, bir dize alan ve her harfi bir diziyle döndüren işlevdir.
export const byLetter = text =>
[...text].map(span)
ES6'teki yayma söz dizimi, bu işlemin hızlı bir şekilde yapılmasına yardımcı oldu.
Kelime bölme yardımcı programı işlevi
Harfleri bölmeye benzer şekilde, bu işlev de bir dize alır ve bir dizideki her kelimeyi döndürür.
export const byWord = text =>
text.split(' ').map(span)
JavaScript dizelerindeki split()
yöntemi, hangi karakterlerin dilimleneceğini belirtmemize olanak tanır.
Kelimeler arasında boşluk olduğunu belirten bir boşluk bıraktım.
Kutuları hizmet işlevi haline getirme
Bu efekt için her harf için kutu gerekir. Bu işlevlerde map()
işlevinin span()
işleviyle çağrıldığını görüyoruz. 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 mülkün ayarlandığını belirtmek önemlidir. Harf animasyonları için kutulara sahip olmak harika bir özellik olsa da CSS'de kullanılacak bir dizinin olması, büyük etkisi olan küçük bir eklemedir.
Bu büyük etkideki en dikkat çeken şey şaşırtıcıdır.
--index
öğesini, kademeli bir görünüm için animasyonları dengelemenin bir yolu olarak
kullanabileceğiz.
Yardımcı Araçlar sonucu
splitting.js
modülü tamamlandığında:
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 kullanmalısınız.
Bölünmüş düzenleme
Bölme yardımcı programları kullanıma hazır olduğunda, tüm bunları bir araya getirmek şu avantajları sağlar:
- Bölünecek öğeleri bulma
- Bunları bölme ve metni HTML ile değiştirme
Ardından CSS devralmayı ve öğelerin / kutuların animasyonunu başlatır.
Öğeleri bulma
İstediğim animasyon ve metnin nasıl bölüneceği hakkındaki bilgileri depolamak için özellikleri ve değerleri kullanmayı tercih ettim. Bu açıklayıcı seçenekleri HTML'ye koymayı sevdim. split-by
özelliği, öğeleri bulmak ve harf veya kelime kutuları oluşturmak için JavaScript'ten kullanılır. letter-animation
veya word-animation
özelliği, öğe alt öğelerini hedeflemek ve dönüştürme ile animasyon uygulamak için CSS'den kullanılır.
Aşağıda, bu iki özelliği gösteren bir HTML örneği verilmiştir:
<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ığı için CSS seçici söz dizimini kullandım:
const splitTargets = document.querySelectorAll('[split-by]')
CSS'de öğeleri 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 bölünmüş hedeflerin her biri 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)
}
})
Düzenleme 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 dilinde okunabilir:
- Bazı yardımcı yardımcı program işlevlerini içe aktarın.
- Bu kullanıcı için hareketin uygun olup olmadığını kontrol edin. Uygun değilse hiçbir işlem yapmayın.
- Bölünmek istenen her öğe için.
- Kullanıcıların 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 dokümanı bölme işlemi, CSS veya JavaScript ile birçok olası animasyon ve efektin kilidini açtı. Bu makalenin alt kısmında, bölünme potansiyelinize ilham verecek birkaç bağlantı verilmiştir.
Bu fırsatı değerlendirin. 4 CSS destekli animasyon ve geçiş paylaşacağım. 🤓
Bölünmüş harfler
Bölünmüş harf efektleri için temel olarak aşağıdaki CSS'yi kullandım. Tüm geçişleri ve animasyonları hareketli medya sorgusunun arkasına koydum ve ardından her yeni alt harf span
'ye bir görüntüleme özelliği ve boşluklarla ne yapılacağıyla ilgili bir stil verdim:
[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 bilgisine sahip eğlenceli konulara geçelim.
Geçiş için bölünmüş harf örneği
Bu örnekte, bölünmüş metin efekti için CSS geçişleri kullanılmaktadır. Geçişlerde, motorun animasyon oluşturması için aralarında geçiş yapacağı durumlara ihtiyacımız var. Ben üç durum seçtim: fareyle üzerine gelme yok, cümlede fareyle üzerine gelme, harfin üzerinde fareyle üzerine gelme.
Kullanıcı cümlenin (yani kapsayıcının) üzerine geldiğinde, tüm alt öğeleri kullanıcı onları uzaklaştırıyormuş gibi küçültüyorum. Sonra, kullanıcı fareyle bir harfinin ü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);
}
}
}
}
Harfleri bölme animasyon örneği
Bu örnekte, her harfi sonsuz olarak animasyonlu hale getirmek için önceden tanımlanmış bir @keyframe
animasyonu kullanılmakta ve satır içi özel mülk dizini, kademeli bir efekt oluşturmak için kullanı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
Bu örneklerde, Flexbox benim için bir kapsayıcı türü olarak çalıştı ve ch
birimini sağlıklı bir boşluk uzunluğu olarak iyi bir şekilde kullandı.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Geçiş için kelimeleri bölme örneği
Bu geçiş örneğinde fareyle üzerine gelme özelliğini tekrar kullanıyorum. Etki, fareyle üzerine gelinene kadar içeriği başlangıçta gizlediğinden, etkileşimin 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 uygulama ö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ç
Bunu nasıl yaptığımı öğrendiğinize göre, siz ne yapardınız? 🙂
Yaklaşımlarımızı çeşitlendirelim ve web'de uygulama geliştirmenin tüm yollarını öğrenelim. Bir Codepen oluşturun veya kendi demonuzu barındırın, bana tweet atın. Ardından, demoyu aşağıdaki Topluluk remiksleri bölümüne ekleyeceğim.
Kaynak
Daha fazla demo ve ilham kaynağı
Topluluk remiksleri
- gnehcwu tarafından CodeSandbox'ta
<text-hover>
web bileşeni