Creating an Interactive 3D Landing Page Using HTML, CSS, and GSAP

shobhitdev
7 Min Read
Creating an Interactive 3D Landing Page Using HTML, CSS, and GSAP

Introduction

Landing pages are a critical aspect of web design, often serving as the first point of contact for visitors. In this article, we’ll explore how you can take your landing page design to the next level using 3D elements and animations. We’ll use HTML, CSS, and JavaScript—with the powerful GSAP library for smooth animations—to create an eye-catching and interactive 3D landing page.

By the end of this article, you’ll be equipped with the knowledge to build a unique landing page that not only engages users but also offers a smooth, interactive experience.

Technologies Used

We’ll focus on three key technologies:

  • HTML for the structure of the page.
  • CSS for styling and layout.
  • GSAP (GreenSock Animation Platform) to add motion and interactivity to the elements.

HTML Structure

We’ll begin by building the foundation of the landing page using HTML. The HTML is relatively straightforward, but it’s essential to structure the page correctly to ensure that our animations and interactivity work smoothly.

Here’s a basic HTML structure for the page:

				
					<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>SVG Illustration - Section transition (gamma.app)</title>
  <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="./style.css">

</head>
<body>
<!-- partial:index.partial.html -->
<main>

<section id="s1">
  <h1 id="a-new-medium-for-presenting-ideas-scroll-further" class="rb-heading-index-3 radial"><h1>
    <span class="radial">A new medium for</span>
    <span class="radial">presenting ideas.</span>
    <span class="smaller">(scroll further)</span>
  </h1></h1>  
</section>

<svg xmlns="http://www.w3.org/2000/svg" fill="#1d0042" stroke="#1d0042" stroke-width="1.8" viewBox="10 0 970 200">

  <g class="ring3">
    <path d="M543.5 60.6C269.8 27.7 1 26.8 1 64.2v386h998v-278c0-27.4-181.8-78.7-455.5-111.6z"/>
    <image mask="url(#m1)" y="35" width="999" height="170" preserveAspectRatio="none" href="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wCEAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDIBERISGBUYLxoaL2NCOEJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY//CABEIAEUBTQMBIgACEQEDEQH/xAAaAAEBAQADAQAAAAAAAAAAAAAAAgEDBQcG/9oACAEBAAAAAOzzQAAAAACus2qva3d1oAAAAX8dV3dXd1dXVVtbu60AAF+Z7V1V3dXd3d1d1dXVVVbu7rQL8jbu1tVW3VXV1d3dXd3V1dXVVVVu8vj2a1ut3d3a2q2ququrq7uru6u6vm8xwA01rdbu7tbW1VVdVdXV8/xuAAANNa3dbW7tVtc/WYAAAABrWt1zf//EABoBAQEBAAMBAAAAAAAAAAAAAAABAgMFBgT/2gAKAgIQAxAAAADm76JZSAAAAAPRdbjWLjXHcaxcazc6zc2WJYAD2fQSyyyy5ubnWbi41i41jWLjWNZuNZeu6MACFIWWWXNlzc3Nxr7vjoAAAAgFlj//xAAeEAACAwEBAQEBAQAAAAAAAAABBBESEwMCAEAgMP/aAAgBAQABAgA+7WmZmZmZmZmZmZmZmZmZmZmZmZmfBLQZDIYDA77a6XtP7efxcDgcDgcDgcDYbDQaDIZDIYDA77a6XtP4ufxYDIZDQaDQbDYbDYcDgcDgcDgcDYbDQaDQZDIZDAYHfbXS9p/vn966aa667DsO47hgMBkMhoNBoNBsNhsNhsNhwOBsNhsNhoNBoMhkMhkMBjcdtefT2bWta97300001122HcdwwGAyGQyGg0Gg2Gw2Gw2Gw2Gw2Gw2Gw0GuTXv/GZm1rWve99NNNddh2Hcdx3DAYDIZDIaDQaDYbDfFv3+SZm1rWve9x00011HYdtx3DHBj1wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxxxxxxyyy48v/EACgQAAMAAwAABAYCAwAAAAAAAAABYVFioQIQISIRMUBBUnESMiAwUP/aAAgBAQADPwD1fuHkeR5Y8seWPLHljyx5Y8seWPLHljyx5Y8seWPLHljyx5Y8seWPLHljyx5Y8seWPLHljyx5Y8seWPLHljyx5Y8sb+PqxfyfqLIsl8kIQhCF9d8z3P1+5SlKUpSlKUpSlEIQhCF9H8x/zfr9ylKUpSlKUpSlKUpSlKUpSiyIQhCEL/R8z3v9/wCL8qPI8lKUpSlKUpSlKUpSlKUpSl8qLIhCF6nv8X7+ipSlKUpSlKUpSlKUpSlKfP1Pf4v39bfKlKUpSlKU/t6nv8X7/wCRT+3qe9+774NuG3Dbhtw24bcNuG3Dbhtw24bcNuG3Dbhtw24bcNuG3Dbhtw24bcNuG3Dbhtw24bcNuG3Dbhtw24bcNuD/AC4P8uD/AC4eL3fDx8P/xAAeEQACAwEBAAMBAAAAAAAAAAAAAQQREhMDECAwQP/aAAgBAgEBPwDkzDMsplfwuOhxhxhxhxhxhxhx2PwZxZyZzZhmWUyvtkyZMGEc0ckcUPxQ/BDjocYcYcYcYcYccccfgcB+L/CiiijJkwYRzRyRxQ/FD8EPwRZZZZZZZZZZZZZZZZZZfwz/xAAbEQEBAQEBAQEBAAAAAAAAAAAAExIRAUAgMP/aAAgBAwEBPwDfjXjvjvxVVVVVVVVUUbb8a8d8d/emm221FFFFFFVVVVVVVVFP4dddaaabbbbUUUU+b//Z"/>
    <mask id="m1" fill="#fff">
      <path d="M999,172c0,32.9-240.3,39.3-514,6.4S1,98.2,1,64c0-37.4,268.8-36.5,542.5-3.6S999,144.6,999,172z M520,64.6 c-193.6-24.6-409.4-26.4-410,5s167.8,65.7,361.4,90.3s421.1,27.9,421.7-3.6S713.6,89.2,520,64.6z"/>
    </mask>
  </g>
  
  <g id="b2">
    <ellipse cx="933.8" cy="172.6" rx="7" ry="46" transform="rotate(-83.812 933.77606 172.57357)" />
    <mask id="m6" fill="#fff" stroke-width="1">
      <circle id="c2" cx="899.2" cy="144.2" r="27.2"/>
    </mask>
    <use fill="#ea42c2" href="#c2"/>
    <circle mask="url(#m6)" cx="917.8" cy="162.8" r="27.2" opacity="0.7"/>
  </g>
  <use href="#b2" x="-853" y="-84" transform="scale(0.87)" />
  
  <g mask="url(#m4)">
    <g class="ring2">
      <path fill="#ff8caf" d="M217 70c0-18.3 128.9-37.2 283.9-38.8C655.8 29.6 782 42.1 782 58M217 70v260h565V58"/>
      <rect x="646" y="64" width="125" height="127"/>
      <path d="M782 58c0 19-135.6 40-290.5 41.5S217 89.8 217 70c0-18.3 128.9-37.2 283.9-38.8C655.8 29.6 782 42.1 782 58z"/>
      <image mask="url(#m2)" width="565" height="69" x="217" y="31" preserveAspectRatio="none" href="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wCEAA4KCw0LCQ4NDA0QDw4RFiQXFhQUFiwgIRokNC43NjMuMjI6QVNGOj1OPjIySGJJTlZYXV5dOEVmbWVabFNbXVkBFRcXHhoeOyEhO3xTRlN8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fP/CABEIADIBRgMBIgACEQEDEQH/xAAaAAEBAQEBAQEAAAAAAAAAAAACAQMABgcF/9oACAEBAAAAAPwMgI3pprpppo203UqqlVbVbb1vzvPMctHrprpo222kqqlVVbVb1t+e5idW9NNNNG020lVUqqrVbetvgQZ3NaPRttNpJVVKqq1W3rb4YHutTbbSTSSqVSqqtVtvW+LJ7uSSTSVaVSqqVVVqtvW3yUk61VJVVJVVVVK1W1W3rb//xAAZAQEBAQEBAQAAAAAAAAAAAAACAQMABgT/2gAKAgIQAxAAAAD0m2uV7LTHXHbLTPTNDhxJhghhhh4zp6759D3BZa5aZa5vOimEmCGGGCTjOnqDZ3RZsPNhGjjCTBDDDBD0nT0as7pQigzTTDDDBCTDxhh7p//EAB8QAQEBAQACAwEBAQAAAAAAAAEAAlEREhAhMDEgIv/aAAgBAQABPwDeny/bOnrOnrO3rG3rGnrGnrZ09bOnrZXrZXrZXrC9hewvYXsL2FhYWFhYWFhYYYYf0Lf9bRJJBBBZLJZsxEREREREREREfB8n+y2fbJOb1vWMwQQQQQRERERERERERHwfkWz/AKZzOb1vWMxmMwQQQQRERERERERER8EfiWs/bOb1vW9YzGYzGYIIIIIiIiIiIiIiPgj8S1n7Zzet63resZjMZgggggiIiIiIiIiI+D8iQ8v0f2Q4Xg4Xg4Xg4Xg4QHC8HCA4QHCA4QHCA5AcvByA5AQEBAQEBAQEBBAQEEEHwfgf2//EABkRAQEAAwEAAAAAAAAAAAAAAAEAAhAgEv/aAAgBAgEBPwDGJmZmZnTMzPQ3q9TlLLMzOnbPRler1OUssszt0z2cMzp2zpnr/8QAGREBAQEBAQEAAAAAAAAAAAAAAQASMEAC/9oACAEDAQE/AGYiIiOyWbMEEER2zZsx8wQQeQ8H/9k="/>
      <g class="mg-back"></g>
      <mask id="m2" fill="#fff">
        <path d="M782 58c0 19-135.6 40-290.5 41.5S217 89.8 217 70c0-18.3 128.9-37.2 283.9-38.8C655.8 29.6 782 42.1 782 58zM508.1 36.3c-86.4 0-182.8 11.2-183 25-.3 13.8 74.9 19.5 161.3 19.5s188-11.2 188.2-25-80-19.5-166.5-19.5z"/>
      </mask>
      <mask id="m4" fill="#fff">
        <path d="M110 69.7c-.6 31.5 167.8 65.7 361.4 90.3s421.1 27.9 421.7-3.6L893 0H109l1 69.7z"/>
      </mask>
      
      
      <g mask="url(#m3)">
        <g class="ring1">
          <path fill="#c307f9" d="M415 8.8C415 3 454.3-1 501.7 1S588 9 588 14M415 8.8V90h173V14"/>
          <rect x="536" y="14" width="45" height="70"/>
          <path fill="#ffa5c0" d="M588 14c0 6-41.7 10.4-89.1 8.4S415 15 415 8.8C415 3 454.3-1 501.7 1S588 9 588 14z"/>    
          <path d="M501 4c-16.6 0-35 2-35 4.5s14.4 3.5 31 3.5 36-1.5 36-4-15.4-4-32-4z"/>
          <mask id="m3" fill="#fff">
            <path d="M674.7,55.7c-0.3,13.8-101.8,25-188.2,25s-161.6-5.6-161.3-19.5L325-0.5h349L674.7,55.7z"/>
          </mask>
        </g>
      </g>
      
      <g class="mg-front">
        <g id="b1">
          <ellipse cx="734" cy="61" rx="33" ry="4" opacity="0.8"/>
          <mask id="m5" fill="#fff" stroke-width="1">
            <circle id="c1" cx="709" cy="42" r="20"/>
          </mask>
          <use fill="#ea42c2" href="#c1"/>
          <g mask="url(#m5)">
            <circle id="b1-dark" cx="724" cy="56" r="20" opacity="0.5"/>
          </g>
        </g>
      </g>
      <path id="b1Path" fill="none" stroke="none" d="M693.8,23.9C693.5,37.4,597,54,462.5,54C296,54,250,43.7,250.2,30.3C250.5,16.8,369,3,487.2,3
		C606,3,694,10.4,693.8,23.9z"/>
    </g>
  </g>
    
</svg>

<section id="s2">
  <h1 id="open-the-door-to-a-new-universe-click-to-pause-the-ball" class="rb-heading-index-4 pink"><h1>
    <span class="pink">Open the door</span>
    <span class="radial">to a new universe</span>
    <span class="smaller pink"><br>(click to pause the ball)</span>
  </h1></h1>
</section>
  
</main>
<!-- partial -->
  <script src='https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js'></script>
<script src='https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/MotionPathPlugin.min.js'></script><script  src="./script.js"></script>

</body>
</html>

				
			

Explanation of the Key Elements:

  • Google Fonts: We use the Abhaya Libre font from Google Fonts to create an elegant and stylish typography for the landing page.
  • SVG Element: The ball is created using an SVG element, which allows for flexible scaling and perfect rendering. We use the <circle> element within the SVG to define the ball.
  • Section Element: The entire landing page content is wrapped inside a <section> tag, which helps with layout management and allows for easy application of styling and animations later on.

CSS for Styling and Layout

Now that the HTML structure is in place, it’s time to bring it to life with some styling. We’ll use CSS to style the page, set the layout, and apply gradients and animations.

				
					@import url('https://fonts.googleapis.com/css2?family=Abhaya+Libre:wght@400;500;600;700;800&display=swap');

html, body {
  margin:0;
  padding:0;
  width:100%;
  height:100%;
  font-family: "Abhaya Libre", serif;
  font-weight: 600;
  font-style: normal;
}

main {
  display:flex;
  justify-content:center;
  flex-direction:column;
}

section {
  display:flex;
  align-items:center;
  justify-content:center;
  width:100%;
  min-height:100vh;
}

#s2 {
  background:#1d0042;
}

svg {
  position:relative;
  margin-top:-9vw;
}

h1 {
  font-size:clamp(3vw, 8.5vw, 99px);
  text-align:center;
}

#s1 h1 {
  font-weight:800;
}

.pink {
  color:rgb(239, 208, 255);
  display:block;
}

.radial {
  -webkit-text-fill-color: transparent;
  background-image: radial-gradient(circle at -20% 0, #2b0aff, #e93abf 31%, #f658a8 48%, #febf72);
  -webkit-background-clip: text;
  background-clip: text;
  display: block;
}

.smaller {
  font-size:0.35em;
  font-weight:500;
}
				
			

Key Points:

  • Responsive Typography: The font-size of the title is controlled using clamp(), which ensures that the font is responsive across devices. It adjusts based on the viewport width (vw).
  • Gradients: We apply a linear gradient to the text in the .title class, giving it a dynamic, multi-colored effect. The background-clip and -webkit-text-fill-color properties make sure the gradient fills only the text area, while the actual text remains transparent.
  • SVG Ball: The ball is sized at 100x100px and positioned with CSS. We keep the ball’s position relative, so we can move it smoothly later using JavaScript.

JavaScript Animations Using GSAP

With the HTML and CSS done, we can now add the real magic: animations. GSAP is a robust JavaScript animation library that allows you to create smooth, high-performance animations. Here, we’ll animate the ball and make it follow a circular path.

				
					const ballTL = gsap.timeline({repeat:-1, defaults:{duration:2, ease:'none'}})
.to('#b1', {
  scale:0.75,
  motionPath:{
  path: "#b1Path",
  align: "#b1Path",
  start: 0.25,
  end: 0.75
}}, 0)
.add(()=>document.querySelector('.mg-back').append(document.querySelector('#b1')), 1)
.to('#b1', {
  scale:1,
  motionPath:{
  path: "#b1Path",
  align: "#b1Path",
  start: 0.75,
  end: 1.25
}}, 2)
.add(()=>document.querySelector('.mg-front').append(document.querySelector('#b1')), 3)
.to('#b1-dark', {scaleY:0.8, ease:'sine.inOut', transformOrigin:'88% 80%', yoyo:true, repeat:1}, 0)
.to('#b1 ellipse', {scale:0.6, ease:'sine.inOut', transformOrigin:'0 50%', yoyo:true, repeat:1}, 0)
.timeScale(0.25)

window.onclick = ()=> ballTL.isActive()? ballTL.pause() : ballTL.play() //toggle play on click

gsap.timeline({
  scrollTrigger:{
    trigger:'#s1',
    start:'0 0',
    endTrigger:'#s2',
    end:'0 0',
    scrub:0.1
  }
})
.to('.ring2', {y:99, scaleY:1.08}, 0)
.fromTo('.ring1', {y:2},{y:60, skewY:3}, 0)
// .from('svg', {attr:{viewBox:'1 0 999 200'}}, 0)
				
			

Key Points:

  • Ball Animation: Using motionPath, we define the path for the ball. The curviness parameter gives the path a smooth curve, and autoRotate ensures that the ball rotates as it follows the path.
  • ScrollTrigger: The title text scales up as the user scrolls down the page, creating an interactive experience where elements respond to user actions.
  • When the user clicks anywhere on the landing page, the ball animation toggles between pause() and play(). This small touch of interactivity can significantly enhance user engagement.

Optimizing Performance

While animations and 3D effects are visually appealing, it’s essential to optimize them to prevent performance issues, especially on mobile devices. Here are a few tips:

  • Use SVGs for Vector Graphics: SVGs scale beautifully without losing quality, and they are lightweight compared to image formats like PNG or JPG.
  • Keep JavaScript Lightweight: Only load the libraries you need (in this case, GSAP) and avoid overloading your page with heavy scripts.
  • Leverage Hardware Acceleration: GSAP automatically takes advantage of hardware acceleration, but you can further optimize by ensuring that CSS properties like transform are used instead of top/left.

Video Preview Of 3D Landing Page

Conclusion

In this article, we’ve built a stunning 3D landing page that combines the power of HTML, CSS, and JavaScript with GSAP for animations. By integrating responsive design, scroll-triggered animations, and interactive elements, we’ve created a landing page that offers a dynamic and engaging user experience.

Feel free to take the concepts from this tutorial and experiment with your own designs—there’s no limit to what you can achieve with these tools!

Share This Article
Leave a comment