<div class="wrapper">
<div class="content">
<header class="header">
<div class="layers">
<div class="layer-title">
<div class="subtitle">Welcome to</div>
<div class="title">Fairy Forest</div>
</div>
<div class="layer layer-base"></div>
<div class="layer layer-middle"></div>
<div class="layer layer-front"></div>
</div>
</header>
<article class="article">
<div class="article-content">
<h2 class="article-title">To be continued</h2>
<p class="article-text">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Omnis
error provident dignissimos facere. Repellendus tempore autem qui!
Quia magnam tempora esse id necessitatibus corrupti mollitia
expedita sapiente cum rerum, ut dicta laboriosam!
</p>
</div>
<div class="copy">© WebDesign Master</div>
</article>
</div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@100;300;400;700;900&display=swap');
:root {
--scrollTop: 0;
--index: calc(1vw + 1vh);
--transition: transform 0.75s cubic-bezier(0.075, 0.5, 0, 1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #010101;
font-family: 'Raleway', sans-serif;
line-height: 1.55;
}
.header {
position: relative;
}
.header::after {
content: '';
position: absolute;
bottom: calc(var(--index) * -4.5);
z-index: 100;
width: 100%;
height: calc(var(--index) * 10);
background-image: url('https://i.ibb.co/DM2Knwf/ground.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.layers {
display: flex;
position: relative;
height: 100vh;
align-items: center;
justify-content: center;
overflow: hidden;
text-align: center;
}
.layer-base {
background-image: url('https://i.ibb.co/gjgkdXX/layer-base.png');
will-change: transform;
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
transform: translateY(calc(var(--scrollTop) / 1.6));
background-size: cover;
background-position: center;
transition: var(--transition);
}
.layer-middle {
background-image: url('https://i.ibb.co/bs5VtZj/layer-middle.png');
will-change: transform;
position: absolute;
height: 100%;
width: 100%;
z-index: 2;
transform: translateY(calc(var(--scrollTop) / 2.5));
background-size: cover;
background-position: center;
transition: var(--transition);
}
.layer-front {
background-image: url('https://i.ibb.co/1fKwBmW/layer-front.png');
will-change: transform;
position: absolute;
height: 100%;
width: 100%;
z-index: 2;
transform: translateY(calc(var(--scrollTop) / 5.7));
background-size: cover;
background-position: center;
transition: var(--transition);
}
.layer-title {
will-change: transform;
position: relative;
z-index: 1;
color: #e7e7e0;
transform: translateY(calc(var(--scrollTop) / 2));
transition: var(--transition);
text-shadow: 0 0 15px #9d822b;
text-transform: uppercase;
font-weight: 900;
}
.title {
margin-bottom: 80px;
font-size: calc(var(--index) * 2.65);
letter-spacing: calc(var(--index) / 2.25);
}
.subtitle {
margin-top: calc(var(--index) * -0.75);
font-size: calc(var(--index) / 1.175);
letter-spacing: calc(var(--index) / 3.5);
}
.article {
position: relative;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: transparent;
background-image: url('https://i.ibb.co/ryQdX3b/dungeon.jpg');
background-size: cover;
background-position: center;
color: #e7e7e0;
text-align: center;
top: -1px;
z-index: 10;
}
.article-title {
text-transform: uppercase;
font-size: calc(var(--index) * 1.8);
letter-spacing: calc(var(--index) / 7.5);
transform: translateY(calc(var(--scrollTop) / -7.5));
transition: var(--transition);
will-change: transform;
}
.article-text {
max-width: calc(var(--index) * 30);
font-size: calc(var(--index) * 0.9);
margin-top: calc(var(--index) / 1.25);
transform: translateY(calc(var(--scrollTop) / -7.5));
transition: var(--transition);
will-change: transform;
}
.content {
will-change: transform;
}
.copy {
position: absolute;
bottom: calc(var(--index) * 2.5);
opacity: 0.45;
font-size: calc(var(--index) * 0.75);
letter-spacing: calc(var(--index) / 37.5);
}
gsap.registerPlugin(ScrollTrigger, ScrollSmoother)
ScrollSmoother.create({
wrapper: '.wrapper',
content: '.content'
});
const handleScroll = () => {
const scrollTop = document.documentElement.scrollTop;
document.documentElement.style.setProperty('--scrollTop', `${scrollTop}px`);
}
document.addEventListener('scroll', () => {
requestAnimationFrame(handleScroll);
});
This Pen doesn't use any external CSS resources.