Una panoramica di base su come creare animazioni di lettere divise e parole.
In questo post voglio condividere idee su come risolvere animazioni e interazioni di testo diviso per il web che siano minime, accessibili e funzionino su tutti i browser. Prova la demo.
Se preferisci i video, ecco una versione di YouTube di questo post:
Panoramica
Le animazioni con testo diviso possono essere sorprendenti. In questo post riusciremo a malapena a tracciare la superficie del potenziale animato, ma fornisce una base su cui sviluppare. L'obiettivo è un'animazione progressiva. Il testo deve essere leggibile per impostazione predefinita, con l'animazione integrata. Gli effetti di movimento del testo suddivisi possono diventare stravaganti e potenzialmente fastidiosi, quindi manipoleremo solo l'HTML o applicheremo stili di movimento se l'utente è d'accordo con il movimento.
Ecco una panoramica generale del flusso di lavoro e dei risultati:
- Prepara le variabili condizionali di movimento ridotte per CSS e JS.
- Prepara le utilità di suddivisione del testo in JavaScript.
- Orchestra le condizioni e le utilità al caricamento della pagina.
- Scrivi transizioni e animazioni CSS per lettere e parole (la parte rad!).
Ecco un'anteprima dei risultati condizionali a cui faremo riferimento:
Se un utente preferisce un movimento ridotto, lasciamo solo il documento HTML e non facciamo animazioni. Se il movimento è OK, procediamo a spezzarlo in fette. Ecco un'anteprima del codice HTML dopo che JavaScript ha suddiviso il testo per lettera.
Preparazione delle condizionali di movimento
La pratica query multimediale @media
(prefers-reduced-motion: reduce)
disponibile verrà utilizzata da CSS e JavaScript in questo progetto. Questa query supporti è la nostra condizione principale
per decidere se dividere o meno il testo. La query multimediale CSS verrà utilizzata per trattenere
transizioni e animazioni, mentre la query multimediale JavaScript verrà utilizzata per
impedire la manipolazione HTML.
Preparazione del condizionale CSS
Ho utilizzato PostCSS per attivare la sintassi di Media Queries Level 5, in cui posso memorizzare una query multimediale booleana in una variabile:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Preparazione del condizionale JS
In JavaScript, il browser fornisce un modo per controllare le query supporti. Ho usato destructuring per estrarre e rinominare il risultato booleano dal controllo delle query supporti:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Posso quindi testare motionOK
e modificare il documento solo se l'utente non ha richiesto di ridurre il movimento.
if (motionOK) {
// document split manipulations
}
Posso controllare lo stesso valore utilizzando PostCSS per attivare la sintassi @nest
dalla
bozza Nesting 1. Ciò mi consente di
archiviare in un'unica posizione tutte le logiche dell'animazione e i relativi requisiti di stile per gli elementi principali
e secondari:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Con la proprietà personalizzata PostCSS e un valore booleano JavaScript, siamo pronti a eseguire l'upgrade condizionale dell'effetto. Passiamo alla sezione successiva, dove suddivido il codice JavaScript per trasformare le stringhe in elementi.
Suddivisione del testo
Le lettere di testo, le parole, le righe e così via non possono essere animate singolarmente con CSS o JS. Per ottenere l'effetto, abbiamo bisogno di scatole. Se vogliamo animare ogni lettera, ogni lettera deve essere un elemento. Se vogliamo animare ogni parola, ogni parola deve essere un elemento.
- Creare funzioni di utilità JavaScript per suddividere le stringhe in elementi
- Orchestra l'uso di queste utilità
Funzione di utilità per dividere le lettere
Un punto di inizio divertente è con una funzione che prende una stringa e restituisce ogni lettera di un array.
export const byLetter = text =>
[...text].map(span)
La sintassi spread di ES6 ha davvero contribuito a rendere questa operazione rapida.
Funzione di utilità di suddivisione delle parole
Analogamente alla suddivisione delle lettere, questa funzione prende una stringa e restituisce ogni parola in un array.
export const byWord = text =>
text.split(' ').map(span)
Il metodo split()
sulle stringhe JavaScript ci consente di specificare i caratteri da suddividere.
Ho superato uno spazio vuoto, che indica una divisione tra le parole.
Funzione di utilità delle scatole
L'effetto richiede caselle per ogni lettera e, come abbiamo notato, in queste funzioni
map()
viene chiamato con una funzione span()
. Ecco la funzione span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
È fondamentale notare che viene impostata una proprietà personalizzata denominata --index
con la posizione dell'array. Avere le caselle per le animazioni con le lettere è un'ottima cosa, ma
avere un indice da utilizzare in CSS è un'aggiunta apparentemente piccola con un grande impatto.
L'aspetto più notevole in questo grande impatto è
sconcertante.
Potremo utilizzare --index
per compensare le animazioni per una visualizzazione sfalsata.
Conclusione dei servizi di pubblica utilità
Il modulo splitting.js
è stato completato:
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)
Ora devi importare e utilizzare le funzioni byLetter()
e byWord()
.
Orchestrazione suddivisa
Con le utility di suddivisione pronte per l'uso, combinare tutto questo significa che:
- Trovare gli elementi da suddividere
- Dividerli e sostituire il testo con HTML
Dopodiché, CSS prende in carico e anima gli elementi / le caselle.
Elementi dei risultati
Ho scelto di usare attributi e valori per memorizzare informazioni
sull'animazione desiderata e su come suddividere il testo. Mi piaceva inserire queste opzioni dichiarative
nel codice HTML. L'attributo split-by
viene utilizzato da JavaScript per trovare
elementi e creare caselle per lettere o parole. L'attributo letter-animation
o word-animation
viene utilizzato da CSS per scegliere come target gli elementi secondari e applicare trasformazioni e animazioni.
Di seguito è riportato un esempio di codice HTML che illustra i due attributi:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Trovare elementi da JavaScript
Ho utilizzato la sintassi del selettore CSS per la presenza degli attributi in modo da raccogliere l'elenco di elementi che vogliono la loro suddivisione del testo:
const splitTargets = document.querySelectorAll('[split-by]')
Trovare elementi da CSS
Ho anche usato il selettore della presenza di attributi in CSS per assegnare le animazioni a tutte le lettere gli stessi stili di base. In seguito utilizzeremo il valore dell'attributo per aggiungere stili più specifici e ottenere un effetto.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Suddivisione del testo in posizione
Per ogni target di suddivisione che troviamo in JavaScript, suddivideremo il testo
in base al valore dell'attributo e mapperemo ogni stringa a un <span>
. Possiamo quindi sostituire il testo dell'elemento con le caselle create:
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)
}
})
Conclusione dell’orchestrazione
index.js
completato:
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)
})
}
Il codice JavaScript potrebbe essere letto nel seguente inglese:
- Importare alcune funzioni di utilità di supporto.
- Controlla se il movimento è consentito per l'utente; in caso contrario, non fare nulla.
- Per ogni elemento che vuoi dividere.
- Suddividili in base a come vuoi che vengano suddivisi.
- Sostituisci il testo con elementi.
Divisione di animazioni e transizioni
La suddetta manipolazione del documento con la suddivisione ha appena sbloccato una moltitudine di potenziali effetti ed animazioni con CSS o JavaScript. Alla fine di questo articolo, troverai alcuni link che ti aiuteranno a individuare il tuo potenziale di suddivisione.
È ora di dimostrare cosa sai fare. condividerò 4 animazioni e transizioni basate su CSS. 🤓
Lettere divise
Come base per gli effetti delle lettere divisa, ho trovato utile il seguente codice CSS. Inserisco tutte le transizioni e le animazioni dietro la query dei contenuti multimediali di movimento e assegno
a ogni nuova lettera secondaria span
una proprietà di visualizzazione e uno stile per
cosa fare con gli spazi bianchi:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
Lo stile degli spazi bianchi è importante per far sì che le sezioni che sono solo uno spazio non vengano compresse dal motore di layout. Passiamo ora alle cose divertenti stateful.
Esempio di lettere divise di transizione
Questo esempio utilizza le transizioni CSS per l'effetto di testo diviso. Nel caso delle transizioni, sono necessari degli stati affinché il motore si anima e scelgo tre stati: nessun passaggio del mouse, passaggio del mouse nella frase, passaggio del mouse su una lettera.
Quando l'utente passa il mouse sopra la frase, ovvero il container, riduco tutti i bambini come se l'utente li avesse spinti più lontano. Poi, quando l'utente passa il mouse sopra una lettera, la inserisco.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Esempio di animazione di lettere divise
Questo esempio utilizza un'animazione @keyframe
predefinita per animare all'infinito ogni lettera e utilizza l'indice di proprietà personalizzate incorporate per creare un effetto sfalsato.
@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;
}
}
Dividi parole
Flexbox ha funzionato come tipo di container per me in questi esempi, sfruttando l'unità ch
come lunghezza dello spazio vuoto.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Esempio di parole divise con transizione
In questo esempio di transizione uso di nuovo il mouse. Inizialmente l'effetto nasconde i contenuti fino al passaggio del mouse, pertanto mi sono assicurato che l'interazione e gli stili venissero applicati solo se il dispositivo aveva la possibilità di passare il mouse sopra.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Esempio di animazione di parole divise
In questo esempio di animazione utilizzo nuovamente CSS @keyframes
per creare
un'animazione infinita sfalsata su un normale paragrafo di testo.
[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;
}
}
Conclusione
Ora che sai come ci sono riuscito, come faresti?! 🙂
Diversifica i nostri approcci e scopriamo tutti i modi per creare sul web. Crea un Codepen o ospita la tua demo, inviami un tweet e lo aggiungerò alla sezione Remix della community qui sotto.
Origine
Altre demo e ispirazione
Remix della community
- Componente web
<text-hover>
di gnehcwu su CodeSandbox