Vissza a webes elemekhez
Fejlécek

Aszimmetrikus fókusz

Élő előnézet – a komponens teljes méretben.

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

    <div class="we-focus-bg"></div>

    <div class="we-focus-frame"></div>

    <div class="we-focus-content">

        <div class="we-focus-meta">
            <span>15</span>
            <i></i>
            <span>FELFEDEZÉS</span>
        </div>

        <h1>
            A részletekben<br>
            <em>rejtőzik</em> a világ.
        </h1>

        <p>
            Egy pillanat, egy hely, egy történet.
            Fedezd fel azt, ami első pillantásra láthatatlan.
        </p>

        <a href="#" class="we-focus-button">
            <span>Felfedezem</span>
            <b>↗</b>
        </a>

    </div>

    <div class="we-focus-image-wrap">
        <div class="we-focus-image"></div>
        <div class="we-focus-image-caption">
            <span>01 / 05</span>
            <span>Ismeretlen tájak</span>
        </div>
    </div>

    <div class="we-focus-corner">
        <span></span>
        <span></span>
    </div>

</div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Bodoni+Moda:opsz,wght@6..96,400;6..96,500;6..96,600&family=DM+Sans:wght@400;500;600&display=swap');

.we-focus-hero {
    --we-focus-image:
        url("https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=1800&q=90");

    position: relative;
    width: 100%;
    min-height: 720px;
    overflow: hidden;
    isolation: isolate;
    background: #080b11;
    color: #fff;
    font-family: "DM Sans", sans-serif;
}

.we-focus-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    background:
        radial-gradient(
            circle at 75% 50%,
            rgba(32, 54, 72, .25),
            transparent 38%
        ),
        linear-gradient(
            90deg,
            #080b11 0%,
            #080b11 42%,
            rgba(8, 11, 17, .82) 70%,
            rgba(8, 11, 17, .5) 100%
        );
}

.we-focus-frame {
    position: absolute;
    inset: 30px;
    z-index: 1;
    border: 1px solid rgba(255,255,255,.1);
    pointer-events: none;
}

.we-focus-content {
    position: relative;
    z-index: 4;
    width: min(1180px, calc(100% - 100px));
    min-height: 720px;
    margin: 0 auto;
    padding: 80px 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;

    opacity: 0;
    transform: translateX(-35px);
    transition:
        opacity 1s ease .35s,
        transform 1.1s cubic-bezier(.22,1,.36,1) .35s;
}

.we-focus-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 30px;
    color: rgba(255,255,255,.48);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .22em;
}

.we-focus-meta i {
    display: block;
    width: 46px;
    height: 1px;
    background: rgba(255,255,255,.3);
}

.we-focus-content h1 {
    max-width: 680px;
    margin: 0;
    font-family: "Bodoni Moda", Georgia, serif;
    font-size: clamp(58px, 7vw, 105px);
    line-height: .94;
    font-weight: 400;
    letter-spacing: -.05em;
}

.we-focus-content h1 em {
    font-style: italic;
    color: rgba(255,255,255,.48);
}

.we-focus-content p {
    max-width: 430px;
    margin: 32px 0 38px;
    color: rgba(255,255,255,.62);
    font-size: 15px;
    line-height: 1.8;
}

.we-focus-button {
    display: inline-flex;
    align-items: center;
    gap: 20px;
    padding: 7px 7px 7px 23px;
    border: 1px solid rgba(255,255,255,.25);
    color: #fff;
    text-decoration: none;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    transition:
        border-color .35s ease,
        background .35s ease,
        transform .35s ease;
}

.we-focus-button b {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    color: #080b11;
    font-size: 18px;
    font-weight: 400;
    transition: transform .4s cubic-bezier(.22,1,.36,1);
}

.we-focus-button:hover {
    border-color: rgba(255,255,255,.7);
    background: rgba(255,255,255,.06);
    color: #fff;
    transform: translateY(-3px);
}

.we-focus-button:hover b {
    transform: rotate(45deg);
}

.we-focus-image-wrap {
    position: absolute;
    z-index: 3;
    top: 50%;
    right: max(7%, calc((100% - 1180px) / 2));
    width: min(390px, 31vw);
    aspect-ratio: .78;
    transform:
        translateY(-50%)
        translateX(45px);

    opacity: 0;
    transition:
        opacity 1.1s ease .15s,
        transform 1.25s cubic-bezier(.22,1,.36,1) .15s;
}

.we-focus-image {
    position: absolute;
    inset: 0;
    background-image: var(--we-focus-image);
    background-size: cover;
    background-position: center;
    filter: saturate(.82);
    border: 1px solid rgba(255,255,255,.32);
    box-shadow:
        0 35px 80px rgba(0,0,0,.5);
}

.we-focus-image::after {
    content: "";
    position: absolute;
    inset: 12px;
    border: 1px solid rgba(255,255,255,.22);
}

.we-focus-image-caption {
    position: absolute;
    left: 0;
    bottom: -34px;
    width: 100%;
    display: flex;
    justify-content: space-between;
    color: rgba(255,255,255,.4);
    font-size: 9px;
    letter-spacing: .15em;
    text-transform: uppercase;
}

.we-focus-corner {
    position: absolute;
    z-index: 5;
    right: 30px;
    bottom: 30px;
    width: 60px;
    height: 60px;
}

.we-focus-corner span:first-child {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 60px;
    height: 1px;
    background: rgba(255,255,255,.3);
}

.we-focus-corner span:last-child {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 1px;
    height: 60px;
    background: rgba(255,255,255,.3);
}

.we-focus-hero.is-loaded .we-focus-content {
    opacity: 1;
    transform: translateX(0);
}

.we-focus-hero.is-loaded .we-focus-image-wrap {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}

@media (max-width: 850px) {

    .we-focus-hero {
        min-height: 760px;
    }

    .we-focus-content {
        width: calc(100% - 70px);
        min-height: 760px;
        padding: 70px 0 280px;
    }

    .we-focus-content h1 {
        max-width: 600px;
        font-size: clamp(52px, 12vw, 82px);
    }

    .we-focus-image-wrap {
        top: auto;
        right: 40px;
        bottom: 75px;
        width: 220px;
        transform: translateY(30px);
    }

    .we-focus-hero.is-loaded .we-focus-image-wrap {
        transform: translateY(0);
    }

    .we-focus-image-caption {
        bottom: -25px;
    }
}

@media (max-width: 550px) {

    .we-focus-hero {
        min-height: 760px;
    }

    .we-focus-frame {
        inset: 18px;
    }

    .we-focus-content {
        width: calc(100% - 50px);
        min-height: 760px;
        padding: 60px 0 260px;
    }

    .we-focus-content h1 {
        font-size: clamp(48px, 15vw, 70px);
    }

    .we-focus-content p {
        font-size: 14px;
        margin: 25px 0 30px;
    }

    .we-focus-image-wrap {
        right: 25px;
        bottom: 65px;
        width: 185px;
    }

    .we-focus-corner {
        right: 18px;
        bottom: 18px;
    }
}

@media (prefers-reduced-motion: reduce) {

    .we-focus-content,
    .we-focus-image-wrap,
    .we-focus-button,
    .we-focus-button b {
        transition: none;
    }
}
JavaScript
document.querySelectorAll(".we-focus-hero").forEach(hero => {

    requestAnimationFrame(() => {
        setTimeout(() => {
            hero.classList.add("is-loaded");
        }, 120);
    });

    const image = hero.querySelector(".we-focus-image-wrap");

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

        const rect = hero.getBoundingClientRect();

        const x = (event.clientX - rect.left) / rect.width;
        const y = (event.clientY - rect.top) / rect.height;

        const moveX = (x - 0.5) * 12;
        const moveY = (y - 0.5) * 10;

        image.style.marginLeft = `${moveX}px`;
        image.style.marginTop = `${moveY}px`;
    });

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

        image.style.marginLeft = "0";
        image.style.marginTop = "0";
    });

});