Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

148
Vistas
Simple appearing animation

Just make a very very simple animation:

p {
  animation: appear 1s linear 1;
  font-family:monospace;
}

@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
<p>Thank you for any helps!</p>

It works, but I am just thinking is it possible to make the first letter appear first, after the first letter appearing, then the second, and finally the last letter (now the whole content of p will appear at the same time)

Does CSS have any selectors to select every characters in the element and is it possible to achieve the effect use CSS only?

I only know first-letter and last-letter selector in css, but not sure if css has selector for every letters

If not only with CSS, I would be also Ok with JS solution?

Appreciate for any helps provided~

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Here's a vanilla JS approach. First we extract the text, empty the element, then rebuild it one character at a time.

let p = document.querySelector('.anim');
// store value
let t = p.innerText.split(''),
  counter = 0
p.innerHTML = '';

let inter = setInterval(() => {
  if (counter == t.length) clearInterval(inter)
  else p.insertAdjacentHTML('beforeend', `<span>${t[counter++]}</span>`);
}, 100)
p.anim span {
  animation: appear 1s linear 1;
}

@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
<p class='anim'>Thank you for any helps!</p>

about 4 years ago · Juan Pablo Isaza Denunciar

0

If a JS-based solution is acceptable, then you can easily achieve this using a combination of DOM manipulation (wrapping each non-space character in a <span> element), and then sequentially toggling a class that runs the animation.

The sequential part can be achieved by simply looping through the generated <span> element, and then awaiting for a promise to be resolved.

In your question it is not clear how you want to be a delay to be calculated: I simply assume you want an arbitrary/customizable delay. In this case, a simple promise-based sleep function can get the job done:

function sleep(ms = 0) {
  return new Promise(r => setTimeout(r, ms));
}

async function fadeInCharacters(el) {
  // NOTE: Use a custom data- attribute to ensure we only target the <span> elements we generate
  el.innerHTML = el.textContent.replace(/([^\s])/g, '<span data-animate>$1</span>');
  for (const span of el.querySelectorAll('span[data-animate]')) {
    span.classList.add('animate');
    await sleep(100);
  }
}

fadeInCharacters(document.querySelector('p'));
.animate {
  animation: appear 1s ease-in-out 1 forwards;
}

span {
  opacity: 0;
}

@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
<p>Thank you for any help!</p>

If you want to wait for each character before fading in the next, then change the await function into something that hooks into the animationend event, although I am inclined to believe this is not what you intend. Just putting it out here for the sake of completeness:

function onAnimationEnd(el) {
  return new Promise(r => el.addEventListener('animationend', () => r()));
}

async function fadeInCharacters(el) {
  // NOTE: Use a custom data- attribute to ensure we only target the <span> elements we generate
  el.innerHTML = el.textContent.replace(/([^\s])/g, '<span data-animate>$1</span>');
  for (const span of el.querySelectorAll('span[data-animate]')) {
    span.classList.add('animate');
    await onAnimationEnd(span);
  }
}

fadeInCharacters(document.querySelector('p'));
.animate {
  animation: appear 1s ease-in-out 1 forwards;
}

span {
  opacity: 0;
}

@keyframes appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
<p>Thank you for any help!</p>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda