Descripción general de cómo crear animaciones con letras y palabras divididas
En esta publicación, compartiré ideas sobre cómo resolver animaciones de texto dividido y interactivas para la Web que son mínimas, accesibles y funcionan en todos los navegadores. Prueba la demostración.
Si prefieres ver un video, aquí tienes una versión de YouTube de esta publicación:
Descripción general
Las animaciones con texto dividido pueden ser sorprendentes. Apenas exploraremos la superficie de potencial de animación en esta publicación, pero proporciona una base para crear . El objetivo es hacer animaciones progresivamente. El texto debe ser legible por de forma predeterminada, con la animación creada en la parte superior. Los efectos de movimiento de texto dividido ser extravagante y potencialmente disruptivo, por lo que solo manipularemos HTML, o aplicar estilos de movimiento si el usuario está bien con el movimiento.
Esta es una descripción general del flujo de trabajo y los resultados:
- Preparar condicional de movimiento reducido variables para CSS y JS.
- Prepara utilidades de texto dividido en JavaScript:
- Organiza los condicionales y utilidades de la página de carga de trabajo.
- Cómo escribir transiciones y animaciones de CSS para letras y palabras (la parte rad).
A continuación, se muestra una vista previa de los resultados condicionales que vamos a obtener:
![captura de pantalla de las Herramientas para desarrolladores de Chrome con el panel de Elements abierto y un movimiento reducido en “reduce” y el h1 se muestra sin dividir](https://web.dev/static/articles/building/split-text-animations/image/screenshot-the-chrome-de-65fd5b490f405.png?authuser=6&hl=es)
Si un usuario prefiere reducir el nivel de movimiento, dejamos el documento HTML tal como está y no hacemos nada. animación. Si el movimiento está bien, vamos a dividirlo en pedazos. Este es un vista previa del HTML después de que JavaScript dividió el texto por letra.
![captura de pantalla de las Herramientas para desarrolladores de Chrome con el panel de Elements abierto y un movimiento reducido en “reduce” y el h1 se muestra sin dividir](https://web.dev/static/articles/building/split-text-animations/image/screenshot-the-chrome-de-fd950f1664ff6.png?authuser=6&hl=es)
Cómo preparar condicionales de movimiento
Se usará la consulta de medios disponible @media
(prefers-reduced-motion: reduce)
de CSS y
JavaScript en este proyecto. Esta consulta de medios es nuestro condicional principal para
decidir dividir el texto o no. La consulta de medios de CSS se usará para retener
transiciones y animaciones, mientras que la consulta de medios de JavaScript se usará para
retener la manipulación de HTML.
Cómo preparar el condicional de CSS
Usé PostCSS para habilitar la sintaxis de las consultas de medios de nivel 5, donde puedo almacenar un valor booleano de consulta de medios en una variable:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
Prepara el condicional de JS
En JavaScript, el navegador proporciona una forma de verificar las consultas de medios. Utilicé desestructuración para extraer y cambiar el nombre del resultado booleano de la verificación de consulta de medios:
const {matches:motionOK} = window.matchMedia(
'(prefers-reduced-motion: no-preference)'
)
Entonces, puedo probar motionOK
y solo cambiar el documento si el usuario no
solicitar que se reduzca el movimiento.
if (motionOK) {
// document split manipulations
}
Puedo verificar el mismo valor usando PostCSS para habilitar la sintaxis @nest
de
Borrador de Nesting 1. Esto me permite
almacenar toda la lógica de la animación y los requisitos de estilo de la
padres e hijos en un solo lugar:
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
Con la propiedad personalizada de PostCSS y un booleano de JavaScript, estamos listos para actualizar el efecto de forma condicional. Eso nos lleva a la siguiente sección, en la que desglosar JavaScript para transformar cadenas en elementos.
División del texto
Las letras de texto, palabras, líneas, etc., no se pueden animar individualmente con CSS o JS. Para lograr el efecto, necesitamos cajas. Si queremos animar cada letra, entonces cada letra debe ser un elemento. Si queremos animar cada palabra, entonces cada la palabra debe ser un elemento.
- Crear funciones de utilidad de JavaScript para dividir cadenas en elementos
- Organiza el uso de estas utilidades
Función de utilidad de división de letras
Un lugar divertido para comenzar es con una función que toma una cadena y devuelve cada una letra en una matriz.
export const byLetter = text =>
[...text].map(span)
El dispersión la sintaxis de ES6 realmente ayudó a que esa tarea fuera una tarea rápida.
Función de utilidad de división de palabras
De manera similar a la división de letras, esta función toma una cadena y devuelve cada palabra en un array.
export const byWord = text =>
text.split(' ').map(span)
El
split()
en cadenas de JavaScript nos permite especificar los caracteres que se deben segmentar.
Pasé un espacio vacío, que indica una división entre palabras.
Hacer que las cajas funcionen
El efecto requiere cuadros para cada letra, y vemos en esas funciones, que
map()
se llama con una función span()
. Esta es la función span()
.
const span = (text, index) => {
const node = document.createElement('span')
node.textContent = text
node.style.setProperty('--index', index)
return node
}
Es fundamental tener en cuenta que una propiedad personalizada llamada --index
se configura con
la posición del array. Tener los cuadros para las animaciones de letras es genial,
tener un índice para usar en CSS es una adición aparentemente pequeña con un gran impacto.
Lo más notable en este gran impacto es
asombroso.
Podremos usar --index
como una forma de compensar las animaciones para una imagen escalonada.
estilo.
Conclusión de servicios públicos
El módulo splitting.js
está completo:
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)
A continuación, importa y usa estas funciones byLetter()
y byWord()
.
Organización de divisiones
Ahora que las utilidades de división están listas para usar, reunir todo significa lo siguiente:
- Encuentra qué elementos dividir
- Dividir los elementos y reemplazar el texto por HTML
Después de eso, CSS toma el control y animará los elementos y cuadros.
Buscar elementos
Elegí usar atributos y valores para almacenar información sobre la
animación y cómo dividir el texto. Me gustó colocar estas opciones declarativas
en el archivo HTML. El atributo split-by
se usa de JavaScript para buscar
y crea cuadros para letras o palabras. El atributo
Se usa letter-animation
o word-animation
desde el CSS hasta el elemento de destino
secundarios y aplicar transformaciones y animaciones.
Este es un ejemplo de código HTML que muestra los dos atributos:
<h1 split-by="letter" letter-animation="breath">animated letters</h1>
<h1 split-by="word" word-animation="trampoline">hover the words</h1>
Cómo buscar elementos en JavaScript
Usé la sintaxis del selector CSS en la presencia de atributos para recopilar la lista de elementos que quieren que se divida el texto:
const splitTargets = document.querySelectorAll('[split-by]')
Cómo buscar elementos de CSS
También usé el selector de presencia de atributos en CSS para dar animaciones de todas las letras. los mismos estilos de base. Más adelante, usaremos el valor del atributo para agregar estilos para lograr un efecto.
letter-animation {
@media (--motionOK) {
/* animation styles */
}
}
División del texto en el lugar
Para cada uno de los objetivos de división que encontremos en JavaScript, dividiremos su texto
según el valor del atributo y asignar cada cadena a un <span>
. Podemos
Luego, reemplazamos el texto del elemento con los cuadros que hicimos:
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)
}
})
Conclusión de la organización
index.js
completado:
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)
})
}
El código JavaScript se puede leer en el siguiente inglés:
- Importar algunas funciones auxiliares de utilidad.
- Comprueba si el movimiento es correcto para este usuario, si no hacer nada.
- Por cada elemento que se desea dividir.
- Divídelos según cómo quieren dividirse.
- Reemplazar el texto por elementos
Cómo dividir animaciones y transiciones
La manipulación de la división de documentos anterior acaba de desbloquear una gran cantidad de posibles animaciones y efectos con CSS o JavaScript. Hay algunos vínculos al final de este artículo para inspirar tu potencial de división.
Es hora de demostrar lo que puedes hacer con esto. Compartiré 4 animaciones basadas en CSS y las transiciones. 🤓
Dividir letras
Como base para los efectos de las letras de división, descubrí que el siguiente CSS tiene las siguientes características:
útil. Coloqué todas las transiciones y animaciones detrás de la consulta de medios de movimiento y
Luego, asigna a cada letra secundaria nueva span
una propiedad de visualización y un estilo para qué
con los espacios en blanco:
[letter-animation] > span {
display: inline-block;
white-space: break-spaces;
}
El estilo de espacios en blanco es importante para que los intervalos sean solo un espacio, no sean contraídos por el motor de diseño. Ahora pasemos a la diversión con estados.
Ejemplo de letras divididas de transición
En este ejemplo, se usan transiciones de CSS para el efecto de texto dividido. Con las transiciones, necesitan estados entre los que se debe animar el motor y elegí tres estados: no colocar el cursor sobre una oración, colocar el cursor sobre una letra
Cuando el usuario coloca el cursor sobre la oración, es decir, el contenedor, reduzco la escala niños como si el usuario los empujara más lejos. Luego, cuando el usuario coloca el cursor sobre la menciono.
@media (--motionOK) {
[letter-animation="hover"] {
&:hover > span {
transform: scale(.75);
}
& > span {
transition: transform .3s ease;
cursor: pointer;
&:hover {
transform: scale(1.25);
}
}
}
}
Ejemplo de animación de letras divididas
En este ejemplo, se usa una animación @keyframe
predefinida para animar cada una de forma infinita
y aprovecha el índice de propiedades personalizadas intercalados para crear un flujo escalonado
efecto.
@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;
}
}
Dividir palabras
Flexbox funcionó como tipo
de contenedor en estos ejemplos.
Aprovecha la unidad ch
como una longitud de espacio saludable.
word-animation {
display: inline-flex;
flex-wrap: wrap;
gap: 1ch;
}
Ejemplo de palabras divididas de transición
En este ejemplo de transición, vuelvo a usar el cursor sobre un elemento. Como el efecto inicialmente oculta la contenido hasta que coloques el cursor sobre ellos, me aseguré de que la interacción y los estilos solo se aplicaran si el dispositivo pudiera colocar el cursor sobre él.
@media (hover) {
[word-animation="hover"] {
overflow: hidden;
overflow: clip;
& > span {
transition: transform .3s ease;
cursor: pointer;
&:not(:hover) {
transform: translateY(50%);
}
}
}
}
Ejemplo de animación de palabras divididas
En este ejemplo de animación, vuelvo a usar CSS @keyframes
para crear una imagen
animación infinita en un párrafo normal de texto.
[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;
}
}
Conclusión
Ahora que sabes cómo lo hice, ¿cómo lo harías? 🙂
Diversifiquemos nuestros enfoques y aprendamos todas las formas de desarrollar en la Web. Crea un CodePen o aloja tu propia demostración, envíame un tweet y la agregaré al Aquí tienes la sección Remixes de la comunidad.
Fuente
Más inspiración y demostraciones
Remixes de la comunidad
- Componente web
<text-hover>
de gnehcwu en CodeSandbox