Vissza az animációkhoz
Szöveganimációk

Középről, páros betűkkel épülő szöveg

Élő előnézet – az animáció teljes méretben.

Élő előnézet
HTML · CSS · JS
HTML
<div class="we-text-pair-card">
    <h2 class="we-text-pair">
        Fedezd fel a világ rejtett csodáit.
    </h2>
</div>
CSS
.we-text-pair-card {
    display: inline-block;
    padding: 34px 46px;
    background: #f4f1e9;
    border: 1px solid rgba(0, 0, 0, .08);
    border-radius: 18px;
    box-shadow: 0 18px 45px rgba(0, 0, 0, .22);
    overflow: hidden;
}

.we-text-pair {
    margin: 0;
    color: #111111;
    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(32px, 5vw, 66px);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: .01em;
    text-align: center;
}

.we-text-pair .we-pair-char {
    display: inline-block;
    opacity: 0;
    transform: translateY(4px) scale(.94);
    filter: blur(2px);
    animation: wePairReveal .72s cubic-bezier(.22, 1, .36, 1) forwards;
}

@keyframes wePairReveal {
    0% {
        opacity: 0;
        transform: translateY(4px) scale(.94);
        filter: blur(2px);
    }

    35% {
        opacity: .55;
        filter: blur(1px);
    }

    70% {
        opacity: .9;
    }

    100% {
        opacity: 1;
        transform: translateY(0) scale(1);
        filter: blur(0);
    }
}
JavaScript
document.querySelectorAll(".we-text-pair").forEach(element => {

    const text = element.textContent.trim();

    element.textContent = "";

    const characters = [...text];

    const visibleIndexes = characters
        .map((char, index) => char === " " ? null : index)
        .filter(index => index !== null);

    const total = visibleIndexes.length;
    const center = (total - 1) / 2;

    characters.forEach((character, index) => {

        const span = document.createElement("span");

        if (character === " ") {
            span.innerHTML = "&nbsp;";
            span.style.opacity = "1";
            span.style.filter = "none";
            span.style.transform = "none";
            span.style.animation = "none";
            element.appendChild(span);
            return;
        }

        span.className = "we-pair-char";
        span.textContent = character;

        const position = visibleIndexes.indexOf(index);
        const distance = Math.abs(position - center);

        /*
         * Középről indul.
         * Mindig egy bal és egy jobb betű jelenik meg.
         * A párok közötti idő most sokkal kisebb,
         * ezért folyamatosabbnak hat.
         */
        const delay = 0.35 + distance * 0.27;

        span.style.animationDelay = `${delay}s`;

        element.appendChild(span);
    });
});