How to Create a TikTok-Like Vertical Scroll Interface with Scroll Direction Indication

Sh Raj - Mar 4 - - Dev Community

How to Create a TikTok-Like Vertical Scroll Interface with Scroll Direction Indication

TikTok, the popular social media platform, has a unique vertical scroll interface that allows users to effortlessly browse through videos. In this tutorial, we'll explore how to create a similar vertical scroll layout using HTML, CSS, and JavaScript. Additionally, we'll add a feature to indicate the direction of the scroll.

Setting Up the HTML Structure

Let's start with the HTML structure for our TikTok-like interface:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TikTok-Like Vertical Scroll</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        body {
            height: 100vh;
            /* overflow: hidden; */
        }

        .center {
            display: flex;
            flex-direction: column; /* Stack videos vertically */
            width: 100vw;
            height: 100vh;
            overflow-y: scroll; /* Allow vertical scrolling */
            scroll-snap-type: y mandatory; /* Snap to each video */
            position: relative;
        }

        .video {
            flex: 0 0 100vh; /* Take full height of viewport */
            width: 100vw;
            scroll-snap-align: start;
            position: relative;
        }

        .video:nth-child(1) {
            background: rgb(198, 85, 85); /* Red */
        }

        .video:nth-child(2) {
            background: rgb(188, 164, 164); /* Gray */
        }

        .video:nth-child(3) {
            background: rgb(85, 134, 198); /* Blue */
        }

        .video:nth-child(4) {
            background: rgb(76, 219, 93); /* Green */
        }

        .video.active {
            border: 2px solid yellow; /* Highlight active video */
        }

        .direction {
            position: fixed;
            top: 10px;
            left: 10px;
            padding: 10px;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            font-size: 16px;
            z-index: 1000;
        }
    </style>
</head>
<body>
    <div class="center" id="center">
        <div class="video" id="video1"></div>
        <div class="video" id="video2"></div>
        <div class="video" id="video3"></div>
        <div class="video" id="video4"></div>
    </div>

    <div class="direction" id="direction"></div>

    <script>
        let prevScrollPos = 0;
        const center = document.getElementById('center');
        const videos = document.querySelectorAll('.video');
        const directionDiv = document.getElementById('direction');

        center.addEventListener('scroll', function() {
            var atSnappingPoint = center.scrollTop % center.offsetHeight === 0;
            var timeOut = atSnappingPoint ? 0 : 150; // Adjust timeout as needed

            clearTimeout(center.scrollTimeout); // Clear previous timeout

            center.scrollTimeout = setTimeout(function() {
                // Using the timeOut to evaluate scrolling state
                if (!timeOut) {
                    console.log('Center snapped!');
                } else {
                    console.log('User stopped scrolling on Center.');
                }
            }, timeOut);

            let currentScrollPos = center.scrollTop;
            let direction = currentScrollPos > prevScrollPos ? 'down' : 'up';
            prevScrollPos = currentScrollPos;

            directionDiv.textContent = `Scroll Direction: ${direction}`;

            // Find the currently active video
            videos.forEach(video => {
                const rect = video.getBoundingClientRect();
                if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
                    // Video is in view
                    video.classList.add('active');
                } else {
                    video.classList.remove('active');
                }
            });
        });
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Explanation

HTML Structure

  • We have a .center container div that holds all the .video divs.
  • Each .video div represents a video in our scroll interface.
  • The .direction div is used to display the scroll direction.

CSS Styling

  • The CSS sets up the basic layout with vertical scrolling and snapping to each video.
  • Different background colors are applied to each video for visual distinction.
  • The .video.active class adds a yellow border to the currently active video.
  • The .direction div is positioned at the top left corner to display the scroll direction.

JavaScript Scroll Handling

  • We use JavaScript to handle the scroll event on the .center div.
  • The scrollHandler function calculates the scroll direction (up or down) and updates the directionDiv.
  • It also adds the .active class to the video that is currently in view, highlighting it with a border.
  • The center div's scroll event listener triggers the `scroll

Handler` when the user scrolls.

Conclusion

In this tutorial, we've created a TikTok-like vertical scroll interface with scroll direction indication. You can further customize this layout by adding your own videos, adjusting colors, and implementing additional features. This layout provides a smooth and engaging way for users to scroll through videos while keeping track of the scroll direction.

Feel free to experiment with the code and make it your own! Happy coding!


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .