Search code examples
htmlcsshtml5-video

Video switching causes unwanted UI bounce


When I switch between my videos by clicking the thumbnails, it seems to cause little bounce as the video gets loaded. Here is a video for better understanding: https://streamable.com/cn5gbn .

<!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="styles.css">
</head>
<body>
    <main>
        <div class="video-container">
            <div class="main-video">
                <video id="main-video-1" class="main-video-element" controls>
                    <source src="1.mp4" type="video/mp4">
                    Your browser does not support the video tag.
                </video>
                <video id="main-video-2" class="main-video-element hidden" controls>
                    <source src="grass.mp4" type="video/mp4">
                    Your browser does not support the video tag.
                </video>
                <video id="main-video-3" class="main-video-element hidden" controls>
                    <source src="sunset.mp4" type="video/mp4">
                    Your browser does not support the video tag.
                </video>
            </div>
            <div class="small-videos">
                <div class="video-item" data-video-id="main-video-2">
                    <img src="grass.png" alt="Grass video thumbnail">
                </div>
                <div class="video-item" data-video-id="main-video-3">
                    <img src="sunset.png" alt="Sunset video thumbnail">
                </div>
            </div>
        </div>
    </main>

    <div class="divider"></div>
    <footer>
        <p>&copy; 2024 My Name. All rights reserved.</p>
    </footer>

    <script src="scripts.js"></script>
</body>
</html>

CSS

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    background-color: #f4f4f4;
    color: #333;
}

main {
    padding: 2rem 0;
    text-align: center;
}

.video-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}

.main-video {
    position: relative;
    width: 100%;
    max-width: 900px;
    height: auto;
    margin-bottom: 1rem;
}

.main-video video {
    width: 100%;
    transition: opacity 0.5s ease;
}

.main-video .hidden {
    opacity: 0;
    pointer-events: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.small-videos {
    display: flex;
    gap: 1rem;
    width: 80%;
    max-width: 900px;
    justify-content: space-between;
}

.small-videos .video-item {
    flex: 1;
    cursor: pointer;
}

.small-videos img {
    width: 100%;
}

.divider {
    width: 80%;
    max-width: 900px;
    height: 1px;
    background-color: #ddd;
    margin: 4rem auto 1rem;
}

footer {
    text-align: center;
    padding: 1rem 0;
}

footer p {
    margin: 0;
    color: #333;
}

@media (max-width: 768px) {
    .main-video {
        width: 100%;
    }

    .small-videos {
        flex-direction: column;
    }

    .small-videos .video-item {
        margin-bottom: 1rem;
    }

    .divider {
        width: 100%;
    }
}

JS:

document.addEventListener("DOMContentLoaded", function() {
    const mainVideos = document.querySelectorAll(".main-video-element");
    const smallVideos = document.querySelectorAll(".video-item");

    smallVideos.forEach(videoItem => {
        videoItem.addEventListener("click", function() {
            const newVideoId = this.getAttribute("data-video-id");
            const newVideoElement = document.getElementById(newVideoId);

            mainVideos.forEach(video => {
                if (video.id === newVideoId) {
                    video.classList.remove("hidden");
                    video.play();
                } else {
                    video.classList.add("hidden");
                    video.pause();
                }
            });
        });
    });
});

My goal is to keep the video boxes aligned in the same position when switching between thumbnails but I am not too sure what is in my code causing this.


Solution

  • All you have to do is place each video element in a div with pre-determined width and height so that video loading doesn't cause bounce in Ui. hope it helps you ;)