Vissza az animációkhoz
Kártyaanimációk

Réteges szétnyílás.

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

Élő előnézet
HTML · CSS · JS
HTML
<div class="we-card-layers">

    <div class="we-card-layers-bg"></div>

    <div class="we-card-layers-frame"></div>

    <div class="we-card-layers-content">

        <span class="we-card-layers-label">
            KÜLÖNLEGES HELY
        </span>

        <h3>Az elveszett világ</h3>

        <p>
            Egy hely, amely úgy hat, mintha egy másik
            korszakból maradt volna ránk.
        </p>

        <span class="we-card-layers-link">
            Felfedezem <b>↗</b>
        </span>

    </div>

</div>
CSS
.we-card-layers {
    position: relative;
    width: min(100%, 420px);
    height: 300px;
    overflow: hidden;

    border-radius: 24px;

    background: #0d1511;
    box-shadow:
        0 20px 50px rgba(0, 0, 0, .35);

    cursor: pointer;
}

.we-card-layers-bg {
    position: absolute;
    inset: -20px;

    background:
        radial-gradient(
            circle at 75% 25%,
            rgba(95, 189, 125, .18),
            transparent 42%
        ),
        linear-gradient(
            135deg,
            #1a2b22,
            #0b1210
        );

    transform: scale(1.04);

    transition:
        transform .9s cubic-bezier(.22, 1, .36, 1),
        filter .8s ease;
}

.we-card-layers-frame {
    position: absolute;
    inset: 18px;

    border: 1px solid rgba(122, 201, 142, .25);
    border-radius: 17px;

    transform:
        translateZ(0)
        scale(.98);

    transition:
        transform .8s cubic-bezier(.22, 1, .36, 1),
        border-color .6s ease;
}

.we-card-layers-content {
    position: absolute;
    inset: 0;
    z-index: 3;

    display: flex;
    flex-direction: column;
    justify-content: flex-end;

    padding: 34px;

    transform: translateY(0);

    transition:
        transform .8s cubic-bezier(.22, 1, .36, 1);
}

.we-card-layers-label {
    margin-bottom: 9px;

    color: #7ac98e;

    font-family: Inter, system-ui, sans-serif;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .18em;
}

.we-card-layers h3 {
    margin: 0 0 10px;

    color: #f4f1e9;

    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(29px, 5vw, 42px);
    font-weight: 500;
    line-height: 1.05;

    transform: translateX(0);

    transition:
        transform .85s cubic-bezier(.22, 1, .36, 1);
}

.we-card-layers p {
    max-width: 310px;
    margin: 0 0 20px;

    color: rgba(244, 241, 233, .68);

    font-family: Inter, system-ui, sans-serif;
    font-size: 14px;
    line-height: 1.65;

    transform: translateX(0);

    transition:
        transform .9s cubic-bezier(.22, 1, .36, 1);
}

.we-card-layers-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;

    color: #f4f1e9;

    font-family: Inter, system-ui, sans-serif;
    font-size: 13px;
    font-weight: 600;

    transform: translateX(0);

    transition:
        transform .8s cubic-bezier(.22, 1, .36, 1),
        color .4s ease;
}

.we-card-layers-link b {
    color: #7ac98e;
    font-size: 18px;
    font-weight: 400;

    transition:
        transform .7s cubic-bezier(.22, 1, .36, 1);
}


/* HOVER */

.we-card-layers:hover .we-card-layers-bg {
    transform:
        scale(1.12)
        translate(-8px, -6px);

    filter: saturate(1.15);
}

.we-card-layers:hover .we-card-layers-frame {
    transform:
        scale(.94)
        translate(5px, -5px);

    border-color: rgba(122, 201, 142, .58);
}

.we-card-layers:hover .we-card-layers-content {
    transform: translateY(-7px);
}

.we-card-layers:hover h3 {
    transform: translateX(7px);
}

.we-card-layers:hover p {
    transform: translateX(14px);
}

.we-card-layers:hover .we-card-layers-link {
    transform: translateX(20px);

    color: #ffffff;
}

.we-card-layers:hover .we-card-layers-link b {
    transform: translate(5px, -3px);
}
JavaScript
document.querySelectorAll(".we-card-layers").forEach(card => {

    const frame = card.querySelector(
        ".we-card-layers-frame"
    );

    card.addEventListener("mousemove", event => {

        const rect = card.getBoundingClientRect();

        const x =
            (event.clientX - rect.left) /
            rect.width;

        const y =
            (event.clientY - rect.top) /
            rect.height;

        const moveX = (x - 0.5) * 8;
        const moveY = (y - 0.5) * 6;

        frame.style.transform = `
            scale(.94)
            translate(
                ${5 + moveX}px,
                ${-5 + moveY}px
            )
        `;
    });

    card.addEventListener("mouseleave", () => {

        frame.style.transform =
            "scale(.98) translate(0, 0)";
    });

});