I'm currently implementing intersection observer to achieve lazy loading for both text and images. In this particular query, I am only focusing on the text aspect of it. The idea is for the text to smoothly transition from 0 opacity to 1 opacity once it comes into view. Specifically, the text should become visible when at least 50% of it is within the viewport of the document. Although the intersection observer is meant to handle this functionality, there seems to be a slight issue with the transition, as if the opacity change isn't triggered by (transform: opacity 3s). Appreciate any help in advance.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Mynerve&family=Nunito&family=Open+Sans&display=swap" rel="stylesheet">
<title>Trelp</title>
</head>
<body>
<div class="container">
<header class='header'>
<img src="images/bgImage.png" alt="Not Loading..." class="bgImage">
<div class="bgImageScreen"></div>
<img src="images/logo.png" alt="Not Loading..." class="logo" width="150px" height="40px">
<div class="title">Build Your<br>Business</div>
<div class="subText">Work with experts to create and grow<br>your business.</div>
<a href=""><div class="learnMore"><h3>Learn More</h3></div></a>
</header>
<section class="section">
<div class="businessTitle hidden">80% of Business Fail</div>
<div class="businessText hidden">Start up businesses fail all around the world.
The majority of times, the business lacks funding, market research, and is poorly planned.
Failure could also stem from the founder having unrealistic expectations about the future of the Business.
This has become an issue, for businesses drive economic growth.
Here at Trelp, we've addressed this issue, and have found a perfect solution.
</div>
<img src="images/business.png" alt="Not Loading..." class="businessImage">
</section>
</div>
<script defer src="script.js"></script>
</body>
</html>
CSS
body {
margin: 0px;
padding: 0px;
}
a {
text-decoration: none;
}
:root {
--black: rgb(0, 0, 0);
--white: rgb(255, 255, 255);
}
.container {
margin: 0px;
padding: 0px;
overflow-y: auto;
overflow-x: hidden;
height: 100vh;
width: 100%;
perspective: 10px;
scroll-behavior: smooth;
}
.bgImage {
width: 100%;
height: 100vh;
object-fit: cover;
transform: translateZ(-10px) scale(2);
}
.bgImageScreen {
position: relative;
bottom: 102%;
width: 100%;
height: 102%;
object-fit: cover;
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.626), black);
transform: translateZ(-10px) scale(2);
}
header {
position: relative;
height: 100%;
transform-style: preserve-3d;
z-index: -1;
}
.logo {
margin: 20px;
position: relative;
bottom: 1470px;
z-index: 3;
}
.title {
color: var(--white);
font-family: 'Open Sans', sans-serif;
font-size: 90px;
position: relative;
bottom: 1400px;
left: 120px;
line-height: 100px;
margin-bottom: 30px;
}
.subText {
color: var(--white);
font-family: 'Open Sans', sans-serif;
font-size: 30px;
position: relative;
bottom: 1400px;
left: 120px;
}
.learnMore {
width: 180px;
height: 70px;
position: relative;
bottom: 1400px;
left: 120px;
font-size: 20px;
font-family: 'Open Sans', sans-serif;
margin-top: 30px;
border: 3px solid var(--white);
background-color: var(--white);
color: var(--black);
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
transition: all 1s;
}
.learnMore:hover {
color: var(--white);
background-color: transparent;
}
.section {
width: 100%;
height: 150vh;
background: var(--black);
margin: 0px;
position: relative;
bottom: 27px;
}
.hidden {
opacity: 0;
transform: opacity 3s;
}
.show {
opacity: 1;
}
.businessImage {
position: relative;
bottom: 400px;
left: 750px;
border-radius: 20px;
}
.businessTitle {
color: green;
font-family: 'Nunito';
font-size: 40px;
position: relative;
top: 150px;
left: 150px;
margin: 30px;
width: 500px;
}
.businessText {
color: green;
font-family: 'Nunito';
font-size: 25px;
width: 500px;
position: relative;
top: 150px;
left: 150px;
line-height: 40px;
margin: 30px;
}
Javascript
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.intersectionRatio >= 0.5) {
entry.target.classList.add('show')
} else {
entry.target.classList.remove('show')
}
})
}, {threshold: [0.5]})
const hiddenElement = document.querySelectorAll('.hidden')
hiddenElement.forEach(el => observer.observe(el))