skip to Main Content

I want to make a title that enters letter-by-letter, similar to the animation of Sliding Text from the Elements WordPress Theme and as animated on this web-page.

Issues

But I don’t know how to make the effect work when the screen arrives at the element as an entrance animation.

I’m using Elementor in WordPress, but I haven’t found ways to do it.

My current code is also on CodePen:

HTML

<h1>
  <div class="slide-in-container">
    <span class="slide-in">Lorem ipsum dolor</span>
    </div><br> 
  <div class="slide-in-container">
    <span class="slide-in2">sit amet, consectetur adipiscing elit.</span>
   </div>
</h1>

CSS

.slide-in, .slide-in2{
  animation: slide-in-animation 1s forwards;
  opacity:0;
}

.slide-in2{
  animation-delay:.5s;
}

@keyframes slide-in-animation {
  from {opacity:0;
  line-height:4em;}
  to {opacity:1;
  line-height:1em;}
}

.slide-in-container{
  overflow-y:hidden;
  display:inline-block;
  vertical-align:middle;
  position:relative;
  height:50px;
  line-height:1.3em!important;
}

Is there a simpler way to do it?

2

Answers


  1. What you need to make that work is the Intersection Observer API (MDN).

    It allows you to place multiple intersection observers across sections. And if a section becomes visible to the user, you are notified. After that, you can add an activation class that starts the transition.

    Login or Signup to reply.
  2. As suggested by @Keimeno, you could use intersection observers.
    .slide-in and .slide-in2 will be added to the span, then it’s atleast 50px above the bottom

    On a side node, div’s should not be placed in h1 tags (or h2-h6). I have added a style to the .slide-in-container class to handle this issue.

    /**
     * Adds a class to a child element
     * @param {Element} obj Target element
     */
    function preloadSlideIn(obj) {
        let child = obj.querySelectorAll('span')[0];
        if (child) {
            if (obj.classList.contains('slide-in-container-first'))
                child.classList.add('slide-in');
            else if (obj.classList.contains('slide-in-container-second'))
                child.classList.add('slide-in2');
        }
    }
    
    // Wait for the DOM to be fully loaded
    (() => {
        const
            slideIns = document.querySelectorAll('.slide-in-container'),
            slideInOptions = {
                threshold: 0,
                rootMargin: "0px 0px -50px 0px"
            };
    
        try {
            const slideInObserver = new IntersectionObserver((entries, slideInObserver) => {
                entries.forEach(o => {
                    if (!o.isIntersecting) return;
    
                    preloadSlideIn(o.target);
                    slideInObserver.unobserve(o.target);
                });
            }, slideInOptions);
    
            slideIns.forEach(o => { slideInObserver.observe(o); });
        } catch (e) {
            // IntersectionObserver is not available for iOS < 12.0
            slideIns.forEach(o => {
                preloadSlideIn(o);
            });
        }
    })();
    body {
      padding: 800px 0;
    }
    .slide-in,
    .slide-in2 {
      animation: slide-in-animation 1s forwards;
      opacity: 0;
    }
    .slide-in2 {
      animation-delay: 0.5s;
    }
    @keyframes slide-in-animation {
      from {
        opacity: 0;
        line-height: 4em;
      }
      to {
        opacity: 1;
        line-height: 1em;
      }
    }
    .slide-in-container {
      font-size: 2rem;
      font-weight: 700;
      overflow-y: hidden;
      vertical-align: middle;
      position: relative;
      height: 50px;
      line-height: 1.3em !important;
    }
    .slide-in-container span {
      opacity: 0;
    }
    <hr />
    <div>
        <div class="slide-in-container slide-in-container-first">
            <span>Lorem ipsum dolor</span>
        </div>
        <div class="slide-in-container slide-in-container-second">
            <span>sit amet, consectetur adipiscing elit.</span>
        </div>
    </div>
    <hr />

    Source: https://w3c.github.io/IntersectionObserver/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search