54

How to create Disney plus clone with pure HTML, CSS, JS

 3 years ago
source link: https://dev.to/kunaal438/how-to-create-disney-plus-clone-for-beginner-in-2021-html-css-js-m3p
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Cover image for How to create Disney plus clone with pure HTML, CSS, JS

How to create Disney plus clone with pure HTML, CSS, JS

Aug 15

・9 min read

Hello, Today we'll see, how we can easily create a disney plus UI clone using HTML, CSS and JS only. No other library. We'll also see how we can make an endless slider effect. Which took me 2-3 hrs to code.

Our clone is very similar to the original disney plus website. It is only one page(homepage) website. It has navbar and search box with cool click effect same as disney+ and it also has a slider or carousel with infinity or endless effect. Which was very hard for me to make at first. And after that we also have movie cards. With awesome card hover effect. And we have much more.

To see demo or you want full coding tutorial video with explanation. You can watch the tutorial below.

Video Tutorial

I appreciate if you can support me by subscribing my youtube channel.

So, without wasting more time let's see how to code this.

Before we start writing our code. Although it's not a Node app but we should see it folder structure at least to with.

Download Template

You can see we have a file named data.js. This file contain our movie slider data. You can see below.

let movies = [
    {
        name: 'falcon and the winter soldier',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 2.PNG'
    },
    {
        name: 'loki',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 1.PNG'
    },
    {
        name: 'wanda vision',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 3.PNG'
    },
/// and so on
]
Enter fullscreen modeExit fullscreen mode

If you see the starting data. You'll notice that our slide-1 is on second number on the list. Why is that. That is because. Our slider will have 3 slides at a time and we want the active slide to be in center. Which means when we first start with slide data. our active slide or first slide will be in middle. I hope this make sense. If not then watch it video tutorial for more better understanding.

Now let's code the webpage.

Webpage.

Start with index.html. Write basic HTML structure and link CSS and JS files. Make sure you add data.js file before app.js. So that we can access the data in app.js file.

Now first create Navbar.

<nav class="navbar">
    <img src="images/logo.png" class="brand-logo" alt="">
    <ul class="nav-links">
        <li class="nav-items"><a href="#">TV</a></li>
        <li class="nav-items"><a href="#">movies</a></li>
        <li class="nav-items"><a href="#">sports</a></li>
        <li class="nav-items"><a href="#">premium</a></li>
    </ul>

    <div class="right-container">
        <input type="text" class="search-box" placeholder="search">
        <button class="sub-btn">subscribe</button>
        <a href="#" class="login-link">login</a>
    </div>
</nav>
Enter fullscreen modeExit fullscreen mode
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    width: 100%;
    background: #0c111b;
    position: relative;
    font-family: roboto, sans-serif;
}

.navbar{
    width: 100%;
    height: 80px;
    position: fixed;
    top: 0;
    left: 0;
    padding: 0 4%;
    background: #0c111b;
    z-index: 9;
    display: flex;
    align-items: center;
}

.brand-logo{
    height: 70px;
}

.nav-links{
    margin-top: 10px;
    display: flex;
    list-style:none;
}

.nav-items a{
    text-decoration: none;
    margin-left: 20px;
    text-transform: capitalize;
    color: #fff;
    opacity: 0.9;
}

.right-container{
    display: block;
    margin-left: auto;
}

.search-box{
    border: none;
    border-bottom: 1px solid #aaa;
    background: transparent;
    outline: none;
    height: 30px;
    color:#fff;
    width: 250px;
    text-transform: capitalize;
    font-size: 16px;
    font-weight: 500;
    transition: .5s;
}

.search-box:focus{
    width: 400px;
    border-color: #1f80e0;
}

.sub-btn{
    background: #1f80e0;
    height: 30px;
    padding: 0 20px;
    color: #fff;
    border-radius: 5px;
    border: none;
    outline: none;
    text-transform: uppercase;
    font-weight: 700;
    font-size: 12px;
    margin: 0 10px;
}

.login-link{
    color: #fff;
    opacity: 0.9;
    text-transform: uppercase;
    font-size: 15px;
    font-weight: 700;
    text-decoration: none;
}
Enter fullscreen modeExit fullscreen mode

Output

Now let's make slider. We'll create these slides with JS but for styling purpose just create one for now in HTML.

div class="carousel-container">
    <div class="carousel">
        <div class="slider">
            <div class="slide-content">
                <h1 class="movie-title">loki</h1>
                <p class="movie-des">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Suscipit saepe eius ratione nostrum mollitia explicabo quae nam pariatur. Sint, odit?</p>
            </div>
            <img src="images/slider 1.PNG" alt="">
        </div>
    </div>
</div>
Enter fullscreen modeExit fullscreen mode
.carousel-container{
    position: relative;
    width: 100%;
    height: 450px;
    padding: 20px 0;
    overflow-x: hidden;
    margin-top: 80px;
}

.carousel{
    display: flex;
    width: 92%;
    height: 100%;
    position: relative;
    margin: auto;
}

.slider{
    flex: 0 0 auto;
    margin-right: 30px;
    position: relative;
    background: rgba(0, 0, 0,0.5);
    border-radius: 5px;
    width: 100%;
    height: 100%;
    left: 0;
    transition: 1s;
    overflow: hidden;
}

.slider img{
    width: 70%;
    min-height: 100%;
    object-fit: cover;
    display: block;
    margin-left: auto;
}

.slide-content{
    position: absolute;
    width: 50%;
    height: 100%;
    z-index: 2;
    background: linear-gradient(to right, #030b17 80%, #0c111b00);
    color: #fff;
}

.movie-title{
    padding-left: 50px;
    text-transform: capitalize;
    margin-top: 80px;
}

.movie-des{
    width: 80%;
    line-height: 30px;
    padding-left: 50px;
    margin-top: 30px;
    opacity: 0.8;
}
Enter fullscreen modeExit fullscreen mode

Output

YOu can comment the slide now. As we are done styling it.
And create this slider working. Watch this to understand the working concept of this slider.

Inside app.js . Select our Carousel element and create an empty array to store all slides.

const carousel = document.querySelector('.carousel');
let sliders = [];

let slideIndex = 0; // to track current slide index.
Enter fullscreen modeExit fullscreen mode

Now create a function createSlide for creating a slide.

const createSlide = () => {
    if(slideIndex >= movies.length){
        slideIndex = 0;
    }

    // creating DOM element
    let slide = document.createElement('div');
    let imgElement = document.createElement('img');
    let content = document.createElement('div');
    let h1 = document.createElement('h1');
    let p = document.createElement('p');
}
Enter fullscreen modeExit fullscreen mode

In this function. In the start we are increasing or setting our next slideIndex with some if/else condition. And after that we are creating DOM element that we need for our slide. These all elements are exactly same as we had in our index.html.

After creating all these elements. Append/attach these elements to one another to form the HTML strucuture.

{
    // attaching all elements
    imgElement.appendChild(document.createTextNode(''));
    h1.appendChild(document.createTextNode(movies[slideIndex].name));
    p.appendChild(document.createTextNode(movies[slideIndex].des));
    content.appendChild(h1);
    content.appendChild(p);
    slide.appendChild(content);
    slide.appendChild(imgElement);
    carousel.appendChild(slide);
}
Enter fullscreen modeExit fullscreen mode

this code is inside createSlide function.

After done appending elements to each other. Now set their class names and set image's source.

{
    // setting up image
    imgElement.src = movies[slideIndex].image;
    slideIndex++;

    // setting elements classname
    slide.className = 'slider';
    content.className = 'slide-content';
    h1.className = 'movie-title';
    p.className = 'movie-des';

    sliders.push(slide);
}
Enter fullscreen modeExit fullscreen mode

And last remember to push the slide inside sliders array.

We are done creating sliders. But our slider won't work why because we have to shift our first slide to the left. For that add this at the end of the function.

{
    if(sliders.length){
        sliders[0].style.marginLeft = `calc(-${100 * (sliders.length - 2)}% - ${30 * (sliders.length - 2)}px)`;
    }
}
Enter fullscreen modeExit fullscreen mode

And now if you create slides. You'll see our slider works or not.

for(let i = 0; i < 3; i++){
    createSlide();
}

setInterval(() => {
    createSlide();
}, 3000);
Enter fullscreen modeExit fullscreen mode

We are done with Sliders. Now create video cards.

<div class="video-card-container">
    <div class="video-card">
        <img src="images/disney.PNG" class="video-card-image" alt="">
        <video src="videos/disney.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/pixar.PNG" class="video-card-image" alt="">
        <video src="videos/pixar.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/marvel.PNG" class="video-card-image" alt="">
        <video src="videos/marvel.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/star-wars.PNG" class="video-card-image" alt="">
        <video src="videos/star-war.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/geographic.PNG" class="video-card-image" alt="">
        <video src="videos/geographic.mp4" mute loop class="card-video"></video>
    </div>
</div>
Enter fullscreen modeExit fullscreen mode
.video-card-container{
    position: relative;
    width: 92%;
    margin: auto;
    height: 10vw;
    display: flex;
    margin-bottom: 20px;
    justify-content: space-between;
}

.video-card{
    position: relative;
    min-width: calc(100%/5 - 10px);
    width: calc(100%/5 - 10px);
    height: 100%;
    border-radius: 5px;
    overflow: hidden;
    background: #030b17;
}

.video-card-image,
.card-video{
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.card-video{
    position: absolute;
}

.video-card:hover .video-card-image{
    display: none;
}
Enter fullscreen modeExit fullscreen mode

Output

And to make video play on hover card. Code this.

/// video cards

const videoCards = [...document.querySelectorAll('.video-card')];

videoCards.forEach(item => {
    item.addEventListener('mouseover', () => {
        let video = item.children[1];
        video.play();
    })
    item.addEventListener('mouseleave', () => {
        let video = item.children[1];
        video.pause();
    })
})
Enter fullscreen modeExit fullscreen mode

This effect will only work if user click on your site first. If use did not click on your page first then the video will not play because of the google chrome policy.

And the last thing. Let's create cards.

    <h1 class="title">recommended for you</h1>
    <div class="movies-list">
        <button class="pre-btn"><img src="images/pre.png" alt=""></button>
        <button class="nxt-btn"><img src="images/nxt.png" alt=""></button>
        <div class="card-container">
            <div class="card">
                <img src="images/poster 1.png" class="card-img" alt="">
                <div class="card-body">
                    <h2 class="name">movie name</h2>
                    <h6 class="des">Lorem ipsum dolor sit amet consectetur.</h6>
                    <button class="watchlist-btn">add to watchlist</button>
                </div>
            </div> 
            ...20+ more cards
        </div>
   </div>
.. repeat this whole block 3-4 times with different card content
Enter fullscreen modeExit fullscreen mode
.title{
    color: #fff;
    opacity: 0.9;
    padding-left: 4%;
    text-transform: capitalize;
    font-size: 22px;
    font-weight: 500;
}

.movies-list{
    width: 100%;
    height: 220px;
    position: relative;
    margin: 10px 0 20px;
}

.card-container{
    position: relative;
    width: 92%;
    padding-left: 10px;
    height: 220px;
    display: flex;
    margin: 0 auto;
    align-items: center;
    overflow-x: auto;
    overflow-y: visible;
    scroll-behavior: smooth;
}

.card-container::-webkit-scrollbar{
    display: none;
}

.card{
    position: relative;
    min-width: 150px;
    width: 150px;
    height: 200px;
    border-radius: 5px;
    overflow: hidden;
    margin-right: 10px;
    transition: .5s;
}

.card-img{
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.card:hover{
    transform: scale(1.1);
}

.card:hover .card-body{
    opacity: 1;
}

.card-body{
    opacity: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    background: linear-gradient(to bottom, rgba(4, 8, 15, 0), #192133 90%);
    padding: 10px;
    transition: 0.5s;
}

.name{
    color: #fff;
    font-size: 15px;
    font-weight: 500;
    text-transform: capitalize;
    margin-top: 60%;
}

.des{
    color: #fff;
    opacity: 0.8;
    margin: 5px 0;
    font-weight: 500;
    font-size: 12px;
}

.watchlist-btn{
    position: relative;
    width: 100%;
    text-transform: capitalize;
    background: none;
    border: none;
    font-weight: 500;
    text-align: right;
    color: rgba(255, 255, 255, 0.5);
    margin: 5px 0;
    cursor: pointer;
    padding: 10px 5px;
    border-radius: 5px;
}

.watchlist-btn::before{
    content: '';
    position: absolute;
    top: 0;
    left: -5px;
    height: 35px;
    width: 35px;
    background-image: url(images/add.png);
    background-size: cover;
    transform: scale(0.4);
}

.watchlist-btn:hover{
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.pre-btn,
.nxt-btn{
    position: absolute;
    top: 0;
    width: 5%;
    height: 100%;
    z-index: 2;
    border: none;
    cursor: pointer;
    outline: none;
}

.pre-btn{
    left: 0;
    background: linear-gradient(to right, #0c111b 0%, #0c111b00);
}

.nxt-btn{
    right: 0;
    background: linear-gradient(to left, #0c111b 0%, #0c111b00);
}

.pre-btn img,
.nxt-btn img{
    width: 15px;
    height: 20px;
    opacity: 0;
}

.pre-btn:hover img,
.nxt-btn:hover img{
    opacity: 1;
}
Enter fullscreen modeExit fullscreen mode

Output

We are almost done. The last thing we have to do is make this card slider working. For that open app.js again.

// card sliders

let cardContainers = [...document.querySelectorAll('.card-container')];
let preBtns = [...document.querySelectorAll('.pre-btn')];
let nxtBtns = [...document.querySelectorAll('.nxt-btn')];

cardContainers.forEach((item, i) => {
    let containerDimensions = item.getBoundingClientRect();
    let containerWidth = containerDimensions.width;

    nxtBtns[i].addEventListener('click', () => {
        item.scrollLeft += containerWidth - 200;
    })

    preBtns[i].addEventListener('click', () => {
        item.scrollLeft -= containerWidth + 200;
    })
})
Enter fullscreen modeExit fullscreen mode

And we are done.

So, that's it. I hope you understood each and everything. If you have doubt or I missed something let me know in the comments.

Articles you may find Useful

I really appreciate if you can subscribe my youtube channel. I create awesome web contents.

Thanks For reading.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK