Fejlécek
Aszimmetrikus fókusz
Élő előnézet – a komponens teljes méretben.
Élő előnézet
HTML · CSS · JS
<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>
@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;
}
}
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";
});
});