Learn how to create a synchronized scrolling two-column layout using HTML, CSS, and JavaScript. This tutorial will walk you through building a responsive design where the main content scrolls vertically and the adjacent images scroll horizontally in parallel.
Improve your readability in:
In this tutorial, we’ll learn how to create a two-column layout where the main content scrolls vertically, while an adjacent column of images scrolls horizontally. We’ll ensure that both columns reach their endpoints at the same time, no matter the length of the content. Final Result (TL;DR) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Two Column Layout</title> </head> <body> <div class="container"> <div id="content" class="content"> <h1>Main Content</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates fugiat reprehenderit quia quam consequatur modi hic inventore totam cumque temporibus Atque numquam quisquam voluptas assumenda porro illo nisi eos dolor! Voluptate sunt sint fugit non deserunt distinctio voluptas, nihil exercitationem laudantium voluptatum molestias eum autem nam blanditiis vero quas suscipit! Doloribus nemo ratione repudiandae velit dolore esse, cumque ex accusamus. Voluptates asperiores, quaerat, ipsum, sint qui facere ut cum dolorem dicta quibusdam magni? Obcaecati iure ratione quibusdam nulla, ullam tempore laudantium ab optio minima repellat aliquid accusantium sed, aperiam dolorum! Esse rerum similique quisquam excepturi libero. Inventore, veritatis. Voluptatem quaerat ex dolore praesentium at officia ea, cupiditate quo est quasi tempora alias ipsa incidunt voluptatum mollitia esse doloribus in cumque? Doloribus animi dolores aliquid! Reprehenderit sunt et, ab in impedit nisi. Sunt numquam hic modi voluptates temporibus, architecto enim qui, earum, minima cum placeat magni illum recusandae provident possimus saepe! Enim libero sapiente provident pariatur quae quisquam voluptas! Ut recusandae tenetur repellat ex veniam dicta, qui nobis quisquam mollitia vero, nulla officiis iusto ipsam iste accusamus necessitatibus. Aliquid, rem nostrum. Ut animi nam beatae! Atque amet modi culpa obcaecati velit porro sint tempora aliquid, praesentium at libero blanditiis fuga vel hic delectus sed soluta deleniti asperiores. Culpa excepturi et sint. Aliquid repudiandae corrupti earum soluta asperiores odit nihil veniam aspernatur dolorum. Exercitationem aut tempora, placeat dolore ad veritatis rem reiciendis, necessitatibus et id numquam repellendus voluptates consequatur totam recusandae corrupti. Laboriosam perferendis, vitae praesentium maiores explicabo totam impedit nesciunt odio animi illum! Ducimus architecto, fuga dignissimos rerum quisquam odio voluptate ipsa dolore alias ea qui optio in tenetur quos obcaecati. Veritatis sint earum accusantium repellendus facilis obcaecati sunt vel reprehenderit esse, dignissimos accusamus vitae ab numquam libero et molestias quam! Nisi fugit tempora consectetur officia eveniet, aliquam repudiandae voluptate quas. Est obcaecati similique tempora impedit! Culpa molestias delectus labore minus nobis, molestiae iste repellat ducimus, numquam quisquam repudiandae quos, vero cumque dolores deserunt nemo ipsum. Laborum itaque molestias ea optio! Quis voluptatibus amet dolore impedit repellat reiciendis quibusdam natus cumque, ipsam, ipsa vitae rerum debitis laudantium iusto saepe? Architecto, iste nobis nostrum nesciunt quibusdam inventore molestias quos? Delectus, totam aspernatur? Id vel veniam quae ab voluptatum aliquid aperiam nam eveniet, numquam velit minus eius. Aut expedita, obcaecati at unde sunt illum eos nisi illo debitis voluptatum consectetur harum, dolores labore!</p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates fugiat reprehenderit quia quam consequatur modi hic inventore totam cumque temporibus Atque numquam quisquam voluptas assumenda porro illo nisi eos dolor! Voluptate sunt sint fugit non deserunt distinctio voluptas, nihil exercitationem laudantium voluptatum molestias eum autem nam blanditiis vero quas suscipit! Doloribus nemo ratione repudiandae velit dolore esse, cumque ex accusamus. Voluptates asperiores, quaerat, ipsum, sint qui facere ut cum dolorem dicta quibusdam magni? Obcaecati iure ratione quibusdam nulla, ullam tempore laudantium ab optio minima repellat aliquid accusantium sed, aperiam dolorum! Esse rerum similique quisquam excepturi libero. Inventore, veritatis. Voluptatem quaerat ex dolore praesentium at officia ea, cupiditate quo est quasi tempora alias ipsa incidunt voluptatum mollitia esse doloribus in cumque? Doloribus animi dolores aliquid! Reprehenderit sunt et, ab in impedit nisi. Sunt numquam hic modi voluptates temporibus, architecto enim qui, earum, minima cum placeat magni illum recusandae provident possimus saepe! Enim libero sapiente provident pariatur quae quisquam voluptas! Ut recusandae tenetur repellat ex veniam dicta, qui nobis quisquam mollitia vero, nulla officiis iusto ipsam iste accusamus necessitatibus. Aliquid, rem nostrum. Ut animi nam beatae! Atque amet modi culpa obcaecati velit porro sint tempora aliquid, praesentium at libero blanditiis fuga vel hic delectus sed soluta deleniti asperiores. Culpa excepturi et sint. Aliquid repudiandae corrupti earum soluta asperiores odit nihil veniam aspernatur dolorum. Exercitationem aut tempora, placeat dolore ad veritatis rem reiciendis, necessitatibus et id numquam repellendus voluptates consequatur totam recusandae corrupti. Laboriosam perferendis, vitae praesentium maiores explicabo totam impedit nesciunt odio animi illum! Ducimus architecto, fuga dignissimos rerum quisquam odio voluptate ipsa dolore alias ea qui optio in tenetur quos obcaecati. Veritatis sint earum accusantium repellendus facilis obcaecati sunt vel reprehenderit esse, dignissimos accusamus vitae ab numquam libero et molestias quam! Nisi fugit tempora consectetur officia eveniet, aliquam repudiandae voluptate quas. Est obcaecati similique tempora impedit! Culpa molestias delectus labore minus nobis, molestiae iste repellat ducimus, numquam quisquam repudiandae quos, vero cumque dolores deserunt nemo ipsum. Laborum itaque molestias ea optio! Quis voluptatibus amet dolore impedit repellat reiciendis quibusdam natus cumque, ipsam, ipsa vitae rerum debitis laudantium iusto saepe? Architecto, iste nobis nostrum nesciunt quibusdam inventore molestias quos? Delectus, totam aspernatur? Id vel veniam quae ab voluptatum aliquid aperiam nam eveniet, numquam velit minus eius. Aut expedita, obcaecati at unde sunt illum eos nisi illo debitis voluptatum consectetur harum, dolores labore!</p> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates fugiat reprehenderit quia quam consequatur modi hic inventore totam cumque temporibus Atque numquam quisquam voluptas assumenda porro illo nisi eos dolor! Voluptate sunt sint fugit non deserunt distinctio voluptas, nihil exercitationem laudantium voluptatum molestias eum autem nam blanditiis vero quas suscipit! Doloribus nemo ratione repudiandae velit dolore esse, cumque ex accusamus. Voluptates asperiores, quaerat, ipsum, sint qui facere ut cum dolorem dicta quibusdam magni? Obcaecati iure ratione quibusdam nulla, ullam tempore laudantium ab optio minima repellat aliquid accusantium sed, aperiam dolorum! Esse rerum similique quisquam excepturi libero. Inventore, veritatis. Voluptatem quaerat ex dolore praesentium at officia ea, cupiditate quo est quasi tempora alias ipsa incidunt voluptatum mollitia esse doloribus in cumque? Doloribus animi dolores aliquid! Reprehenderit sunt et, ab in impedit nisi. Sunt numquam hic modi voluptates temporibus, architecto enim qui, earum, minima cum placeat magni illum recusandae provident possimus saepe! Enim libero sapiente provident pariatur quae quisquam voluptas! Ut recusandae tenetur repellat ex veniam dicta, qui nobis quisquam mollitia vero, nulla officiis iusto ipsam iste accusamus necessitatibus. Aliquid, rem nostrum. Ut animi nam beatae! Atque amet modi culpa obcaecati velit porro sint tempora aliquid, praesentium at libero blanditiis fuga vel hic delectus sed soluta deleniti asperiores. Culpa excepturi et sint. Aliquid repudiandae corrupti earum soluta asperiores odit nihil veniam aspernatur dolorum. Exercitationem aut tempora, placeat dolore ad veritatis rem reiciendis, necessitatibus et id numquam repellendus voluptates consequatur totam recusandae corrupti. Laboriosam perferendis, vitae praesentium maiores explicabo totam impedit nesciunt odio animi illum! Ducimus architecto, fuga dignissimos rerum quisquam odio voluptate ipsa dolore alias ea qui optio in tenetur quos obcaecati. Veritatis sint earum accusantium repellendus facilis obcaecati sunt vel reprehenderit esse, dignissimos accusamus vitae ab numquam libero et molestias quam! Nisi fugit tempora consectetur officia eveniet, aliquam repudiandae voluptate quas. Est obcaecati similique tempora impedit! Culpa molestias delectus labore minus nobis, molestiae iste repellat ducimus, numquam quisquam repudiandae quos, vero cumque dolores deserunt nemo ipsum. Laborum itaque molestias ea optio! Quis voluptatibus amet dolore impedit repellat reiciendis quibusdam natus cumque, ipsam, ipsa vitae rerum debitis laudantium iusto saepe? Architecto, iste nobis nostrum nesciunt quibusdam inventore molestias quos? Delectus, totam aspernatur? Id vel veniam quae ab voluptatum aliquid aperiam nam eveniet, numquam velit minus eius. Aut expedita, obcaecati at unde sunt illum eos nisi illo debitis voluptatum consectetur harum, dolores labore!</p> </div> <div id="pictures" class="pictures"> <div class="horizontal-scroll"> <img src="https://picsum.photos/seed/picsum1/300/300" alt="Image 1"> <img src="https://picsum.photos/seed/picsum2/300/300" alt="Image 2"> <img src="https://picsum.photos/seed/picsum3/300/300" alt="Image 3"> <img src="https://picsum.photos/seed/picsum4/300/300" alt="Image 4"> <img src="https://picsum.photos/seed/picsum5/300/300" alt="Image 5"> <img src="https://picsum.photos/seed/picsum6/300/300" alt="Image 6"> <img src="https://picsum.photos/seed/picsum7/300/300" alt="Image 7"> <img src="https://picsum.photos/seed/picsum8/300/300" alt="Image 8"> <img src="https://picsum.photos/seed/picsum9/300/300" alt="Image 9"> <img src="https://picsum.photos/seed/picsum10/300/300" alt="Image 10"> <img src="https://picsum.photos/seed/picsum11/300/300" alt="Image 11"> <img src="https://picsum.photos/seed/picsum12/300/300" alt="Image 12"> <img src="https://picsum.photos/seed/picsum13/300/300" alt="Image 13"> </div> </div> </div> </body> </html> <!-- stylesheet --> <style> body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; } .container { display: flex; height: 100%; } .content { flex: 1; overflow-y: auto; padding: 20px; } .pictures { width: 50%; /* Adjust the width as needed */ overflow-x: auto; overflow-y: hidden; } .horizontal-scroll { display: flex; height: 100%; align-items: center; } .horizontal-scroll img { height: 200px; /* Adjust the height as needed */ margin-right: 10px; } </style> <!-- script --> <script> document.addEventListener('DOMContentLoaded', function() { const content = document.getElementById('content'); const horizontalScroll = document.getElementById('pictures'); content.addEventListener('scroll', function() { const contentHeight = content.scrollHeight - content.clientHeight; const scrollRatio = content.scrollTop / contentHeight; const horizontalScrollWidth = horizontalScroll.scrollWidth - horizontalScroll.clientWidth; horizontalScroll.scrollLeft = scrollRatio * horizontalScrollWidth; }); }); </script> HTML and CSS Setup We’ll begin by setting up the HTML structure and then styling it with CSS to ensure proper alignment and smooth scrolling behavior. HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Two Column Layout</title> </head> <body> <div class="container"> <div id="content" class="content"> <h1>Main Content</h1> <p>... Your content here ...</p> </div> <div id="pictures" class="pictures"> <div class="horizontal-scroll"> <img src="https://picsum.photos/seed/picsum1/300/300" alt="Image 1"> <img src="https://picsum.photos/seed/picsum2/300/300" alt="Image 2"> <img src="https://picsum.photos/seed/picsum3/300/300" alt="Image 3"> <img src="https://picsum.photos/seed/picsum4/300/300" alt="Image 4"> <img src="https://picsum.photos/seed/picsum5/300/300" alt="Image 5"> <img src="https://picsum.photos/seed/picsum6/300/300" alt="Image 6"> <img src="https://picsum.photos/seed/picsum7/300/300" alt="Image 7"> <img src="https://picsum.photos/seed/picsum8/300/300" alt="Image 8"> <img src="https://picsum.photos/seed/picsum9/300/300" alt="Image 9"> <img src="https://picsum.photos/seed/picsum10/300/300" alt="Image 10"> <img src="https://picsum.photos/seed/picsum11/300/300" alt="Image 11"> <img src="https://picsum.photos/seed/picsum12/300/300" alt="Image 12"> <img src="https://picsum.photos/seed/picsum13/300/300" alt="Image 13"> </div> </div> </div> <script src="script.js"></script> </body> </html>
The .container div includes two child divs: .content for the main content and .pictures for the images. The .horizontal-scroll div inside .pictures contains the images and enables horizontal scrolling. CSS body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; } .container { display: flex; height: 100%; } .content { flex: 1; overflow-y: auto; padding: 20px; } .pictures { width: 50%; /* Adjust the width as needed <em>/ overflow-x: auto; overflow-y: hidden; } .horizontal-scroll { display: flex; height: 100%; align-items: center; } .horizontal-scroll img { height: 200px; /</em> Adjust the height as needed */ margin-right: 10px; } The body and html elements are set to have no margin or padding and occupy the full height of the viewport. The .container uses display: flex to position its child divs side by side. The .content div occupies the remaining space (flex: 1) and has vertical scrolling enabled (overflow-y: auto). The .pictures div has a fixed width and allows horizontal scrolling (overflow-x: auto), while vertical scrolling is disabled (overflow-y: hidden). The .horizontal-scroll div employs display: flex to align its child images horizontally. Images within .horizontal-scroll are styled for consistent height and spacing. JavaScript for Synchronized Scrolling To synchronize the scrolling of the main content and the pictures, we use JavaScript to link the vertical scrolling of the main content with the horizontal scrolling of the pictures in a proportional manner. Javascript document.addEventListener('DOMContentLoaded', function() { const content = document.getElementById('content'); const horizontalScroll = document.getElementById('pictures'); content.addEventListener('scroll', function() { const contentHeight = content.scrollHeight - content.clientHeight; const scrollRatio = content.scrollTop / contentHeight; const horizontalScrollWidth = horizontalScroll.scrollWidth - horizontalScroll.clientWidth; horizontalScroll.scrollLeft = scrollRatio * horizontalScrollWidth; }); }); We add an event listener to the .content div to detect scrolling events. The contentHeight is calculated as the total scrollable height of the main content minus its visible height. The scrollRatio is determined by dividing the current vertical scroll position by the total scrollable height. The horizontalScrollWidth is the total scrollable width of the horizontal scroll area minus its visible width. We set horizontalScroll.scrollLeft to the scrollRatio multiplied by the horizontalScrollWidth, ensuring the horizontal scroll position matches the vertical scroll proportionally. Conclusion With this setup, we’ve successfully created a responsive two-column layout where the main content scrolls vertically while the adjacent images scroll horizontally in sync. The JavaScript code ensures that both columns reach their endpoints simultaneously, providing a smooth and synchronized scrolling experience. You can adjust the CSS properties to suit your design needs and add more content and images to see the effect in action.
Originally published at https://blog.ardenov.com.
Top comments (0)