Creating a Scrollable Sticky Sidebar using CSS and JavaScript Tutorial

In this tutorial, you will learn how to create Scrollable Sticky Sidebar using CSS and JavaScript. The main purpose of this tutorial is to provide students and beginners with a reference to learn some CSS and JS tricks that are useful for building a creative website. Here, I will be providing simple web page scripts that demonstrate how the scrollable sticky sidebar can be achieved.

What is a Scrollable Sticky Sidebar?

This tutorial refers to a simple sticky sidebar of the website or web application. This feature or component is often used in websites such as CMS (Content Management System) sites where developers place some widgets on the page sidebar. Although this component is scrollable, this has no scrollbar on its own which means it scrolls along with the main wrapper container of the page.

How to create a Scrollable Sticky Sidebar?

The Scrollable Sticky Sidebar can be easily achieved using CSS useful properties and JS event listeners and built it element properties. Yes, we can create a scrollable sticky sidebar using CSS only but it will only await the remaining scroll area of the content wrapper and the sidebar to be able the sidebar reaches the bottom of the sidebar's content. But, here we will make the sidebar scroll along with the main wrapper and stop and stick to the side of the page showing the bottom area of the sidebar if the main wrapper content is longer than the sidebar. Check out the web page scripts I created below to understand it more.

Sample Web Page

The scripts below will result in a simple web page that contains static and skeleton content that simulates the site article list and sidebar widget. The sidebar container is scrollable yet sticky when reaches the end of its area first.

Page Interface

The script below is the HTML file script named index.html. It contains the page layout elements whereas the main container/wrapper and its sample item and the sidebar container and its sample widget item.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <meta charset="UTF-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>JS - Scrollable Sticky Sidebar</title>
  7. <link rel="preconnect" href="https://fonts.googleapis.com">
  8. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  9. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
  10. <link rel="stylesheet" href="style.css">
  11. <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  12. </head>
  13. <div class="content-md-lg py-3">
  14. <div class="page-title">Scrollable Sticky Sidebar using JavaScript</div>
  15. <hr style="margin:auto; width:25px" class="border-light opacity-100">
  16. <div class="container-lg">
  17. <div class="row py-3">
  18. <!-- Main Content Wrapper -->
  19. <div id="main-content-list" class="col-lg-7 col-md-7 col-sm-7 col-7">
  20. <div class="card shadow rounded-0 bg-dark mb-3 border-dark-subtle content-item">
  21. <div class="card-body">
  22. <div class="container-fluid">
  23. <div class="img-content"></div>
  24. <div class="title-content"></div>
  25. <div class="description-content"></div>
  26. <div class="description-content"></div>
  27. <div class="description-content"></div>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. <!-- Main Content Wrapper -->
  33. <!-- Sidebar Wrapper -->
  34. <div class="col-lg-5 col-md-5 col-sm-5 col-5 position-relative">
  35. <div id="sidebar">
  36. <div class="card shadow rounded-0 bg-dark mb-3 border-dark-subtle sidebar-item">
  37. <div class="card-body">
  38. <div class="container-fluid">
  39. <div class="position-relative d-flex flex-wrap">
  40. <div class="img-content"></div>
  41. <div class="title-content"></div>
  42. </div>
  43. <div class="description-content"></div>
  44. <div class="description-content"></div>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. </div>
  50. <!-- Sidebar Wrapper -->
  51. </div>
  52. </div>
  53. </div>
  54. <script src="script.js"></script>
  55. </body>
  56. </html>

Stylesheet

Next, here is the CSS file script known as style.css. The script contains the custom style codes of some of the page elements.

  1. @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@200&family=Space+Mono&display=swap" rel="stylesheet');
  2. :root{
  3. --space-mono-font: 'Space Mono', monospace;
  4. --border-dark-subtle: #3c3c3c!important;
  5. }
  6. *{
  7. box-sizing: border-box;
  8. }
  9. body *{
  10. font-family: var(--space-mono-font);
  11. }
  12. /**
  13. Page Design
  14. */
  15. body,
  16. html{
  17. height: 100%;
  18. width: 100%;
  19. margin: 0;
  20. padding: 0;
  21. }
  22. body{
  23. background-color: #282A3A;
  24. }
  25. .page-title{
  26. font-size: 2.5rem;
  27. font-weight: 500;
  28. color: #fff;
  29. letter-spacing: 3px;
  30. font-family: var(--secular-font);
  31. text-align: center;
  32. text-shadow: 0px 0px 3px #2020208c;
  33. }
  34. .border-dark-subtle{
  35. border-color: var(--border-dark-subtle)
  36. }
  37.  
  38. /* Main content container and its items */
  39. #main-content-list{
  40. counter-reset : imgCount;
  41. }
  42. #main-content-list .img-content{
  43. display: relative;
  44. width: 75%;
  45. height: 150px;
  46. display:flex;
  47. align-items: center;
  48. justify-content: center;
  49. margin: auto;
  50. background-color: aliceblue;
  51. }
  52. #main-content-list .img-content:before{
  53. counter-increment: imgCount;
  54. content: counter(imgCount);
  55. font-size: 1.3rem;
  56. font-weight:bold;
  57. color:#c1c1c1;
  58. }
  59. #main-content-list .title-content{
  60. width: 75%;
  61. height: 1.3rem;
  62. margin:.5em 0;
  63. background-color: aliceblue;
  64. }
  65. #main-content-list .description-content{
  66. width: 100%;
  67. height: 1rem;
  68. margin:.5em 0;
  69. background-color: aliceblue;
  70. }
  71. /* sidebar container and its items */
  72. #sidebar{
  73. counter-reset: sideimgCount;
  74. width: 100%;
  75. }
  76. #sidebar .img-content{
  77. position: relative;
  78. width: 60px;
  79. height: 60px;
  80. display: flex;
  81. align-items: center;
  82. justify-content: center;
  83. margin: auto;
  84. background-color: aliceblue;
  85. }
  86. #sidebar .img-content:before{
  87. counter-increment: sideimgCount;
  88. content: counter(sideimgCount);
  89. font-size: 1rem;
  90. font-weight:bold;
  91. color:#c1c1c1;
  92. }
  93. #sidebar .title-content{
  94. width: calc(90% - 80px);
  95. height: 1.3rem;
  96. margin:.5em 0;
  97. background-color: aliceblue;
  98. }
  99. #sidebar .description-content{
  100. width: 100%;
  101. height: 1rem;
  102. margin:.5em 0;
  103. background-color: aliceblue;
  104. }

JavaScript

Lastly, here is the JavaScript file script named script.js. It contains the JS codes for cloning the sample main content items and sidebar widgets to make the page scrollable so we can simulate the functionality of the scrollable sticky sidebar. It also contains the window scroll event listener and triggers the sidebar stick and displays the bottom area of its content.

  1. // Main Content Selector
  2. const MainContent = document.getElementById('main-content-list')
  3.  
  4. // Sidebar Selector
  5. const sidebar = document.getElementById('sidebar')
  6.  
  7. //Main content First Item
  8. const mainContentItem = MainContent.querySelector('.content-item:nth-child(1)')
  9. //Sidebar's First Item
  10. const sidebarItem = sidebar.querySelector('.sidebar-item:nth-child(1)')
  11.  
  12. /** Cloning the main content and sidebar content to make the page scrollabel */
  13. window.addEventListener('load', () => {
  14. /** cloning the Main content item 9 times to have a total of 10 main content items */
  15. for(var i=0; i < 9; i++){
  16. var clonedItem = mainContentItem.cloneNode(true)
  17. MainContent.appendChild(clonedItem)
  18. }
  19. /** cloning the Sidebar item 4 times to have a total of 5 Sidebar items */
  20. for(var i=0; i < 4; i++){
  21. var clonedItem = sidebarItem.cloneNode(true)
  22. sidebar.appendChild(clonedItem)
  23. }
  24. })
  25.  
  26. /** watch or listen if the client page is scrolled */
  27. window.addEventListener('scroll', () => {
  28. // Getting the sidebar excess height to viewport
  29. var sidebarBase = sidebar.getBoundingClientRect().height - window.innerHeight;
  30. // current Scroll
  31. var currentScrollY = window.scrollY
  32.  
  33. if(currentScrollY >= sidebarBase){
  34. /**
  35.   * Setting sidebar position as sticky when scroll is greater than/equal to exces height and display the bottom items until the end of scroll
  36.   */
  37. sidebar.style.position = 'sticky'
  38. sidebar.style.top = `-${sidebarBase}px`
  39. }
  40. })

Snapshots

Here are the snapshots of the overall result of the scripts I have provided above.

Unscrolled Page Interface

Scrollable Sticky Sidebar using CSS and JS

Reaches the Bottom of the Sidebar Content

Scrollable Sticky Sidebar using CSS and JS

Reaches the Bottom of the Web Page

Scrollable Sticky Sidebar using CSS and JS

There you go! I have also provided the complete source code zip file that I created for this tutorial on this site and it is free to download. The download button can be found below this tutorial's content. Feel free to download it so you can test the script that I created on your local machine and do some experiments to enhance your programming capabilities.

That's it! I hope this Creating a Scrollable Sticky Sidebar using CSS and JavaScript Tutorial will help you with what you are looking for and will be useful for your current and future web application projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding =)

Add new comment