Hello Sunil
sidebar-sticky-on-scroll-feature-image

How To Make a Sidebar Sticky On Scroll

Have you ever been on a website where an element “sticks” to the screen and follows you as you scroll down the page? This is what I call a sticky sidebar.

In the past, this functionality was frequently accomplished through JavaScript calculations to detect the scroll position and to toggle an element’s position to absolute or fixed.

Presently, the W3C specification has defined sticky positioning, and many modern browsers have already adopted it.

A sticky sidebar is a web design technique to keep the sidebar on the screen even if the user has scrolled past the position where it initially displayed. This is useful for making sub-navigation easily accessible, highlighting your content in your sidebar more as a user scrolls, and potentially increasing your ad impressions, clicks, and page views

This means that we can build a sticky sidebar using just two lines of CSS, with no JavaScript required! Let me show you how.

Sticky Position Example – 1

First set up two divs. One represents the main page content and should extend past the bottom of the screen. The second will be the sidebar, which we will make shorter than the length of the screen, so we can clearly see it moving in our example.

<body>
	<div class="wrapper">
		<div class="main">
			Main Content
		</div>
		<div class="sidebar">
			Sticky Sidebar
		</div>
	</div>
</body>
body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
	background-color: #cccccc;
	padding: 10px;
}



.wrapper {
	display: flex;
	justify-content: space-between;
}

.main,
.sidebar {
	border: 3px solid #000000;
	padding: 15px;
	background-color: #ffffff;
}

.main {
	width: 60%;
	height: 150vh;
}

.sidebar {
	width: 25%;
	height: 25vh;
}

Note the heights of the main and sidebar elements are set using vh units. 100vh is the height of the current viewport, so setting the height of the main div to 150vh gives it a height that will be 1.5 times that of the screen.

But the sidebar isn’t sticky yet! When you scroll down the page, the sidebar doesn’t follow. All we need to do to fix that is to add two lines of CSS:

.sidebar {
	position: sticky;
	top: 0;
}

The specification for using position: sticky requires a direction like top or bottom to be specified with a value other than auto.

Output:

See the Pen Sticky Position Example -1 by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

The position: sticky property tells the element to stick to the screen and the top value tells the element where to sit relative to the screen as it scrolls. We could change this to top: 5% to leave a gap, or for example left: 0, depending on the direction of the scroll.

Sticky Position Example – 2

This code creates a div with the sticky class and another div with the placeholder class that is the full height of the viewport.

<body>
	<div class="sticky-example sticky">Sticky</div>
	<div class="placeholder-example">Placeholder</div>
</body>
* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
	padding: 0;
}

body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
}



.placeholder-example {
	background: lavender;
	height: 100vh;
	padding: 1em;
}

.sticky-example {
	background: cornflowerblue;
	padding: 1em;
}

.sticky {
	position: sticky;
	top: 0;
}

Output:

See the Pen Sticky Position Example -2 by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

Sticky Position Example – 3 (Bootstrap)

The desired layout will have a sidebar that will sit adjacent to a long block of content. You can achieve this with the Bootstrap library too.

In order to achieve the desired layout, your body content will need to adopt the Bootstrap markup structure:

<body>
	<article>
		<div class="container-fluid">
			<div class="row">
				<div class="col">
					<div class="title-section">
						<h1>Stacking Sticky Sidebars with Bootstrap</h1>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-7">
					<div class="content-section">
						Content Section
					</div>
				</div>
				<div class="col-5">
					<div class="sidebar-section">
						<div class="sidebar-item sticky-top">
							<div class="sidebar-content">
								Container 1
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</article>
</body>

This markup establishes a content-section that stretches 7 column widths and a Sidebar Section that stretches 5 column widths. This adds up to 12 columns, which is the default grid system in Bootstrap.

Bootstrap also comes with a utility class named sticky-top that is functionally the same as the sticky class we created earlier.

Before you apply sticky-top, add some styles to help make the the content and sidebar sections more visually apparent:

body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
}



.content-section {
	background: lavender;
	height: 1000px;
	min-height: 100vh;
	padding: 1em;
}

.sidebar-section {
	height: 100%;
}

.sidebar-content {
	background: cornflowerblue;
	padding: 1em;
	color: #ffffff;
}

Now, add the sticky-top class to the sidebar-item:

Output:

See the Pen Sticky Position Example -3 (Bootstrap) by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

When scrolling down the page, the sidebar should have “sticky” behavior.

Advanced Scenarios

Scenarios – 1 :  Sticky Sidebar and Multiple Items

Building off the example, you can add additional items to the sidebar:

When visiting HTML file in the web browser, we should observe a content section and multiple sidebar items.

<body>
	<article>
		<div class="container-fluid">
			<div class="row">
				<div class="col">
					<div class="title-section">
						<h1>Stacking Sticky Sidebars with Bootstrap</h1>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-7">
					<div class="content-section">
						Content Section
					</div>
				</div>
				<div class="col-5">
					<div class="sidebar-section">

						<div class="sidebar-item sticky-top">
							<div class="sidebar-content">
								Container 1
							</div>
						</div>

						<div class="sidebar-item sticky-top">
							<div class="sidebar-content">
								Container 2
							</div>
						</div>

						<div class="sidebar-item sticky-top">
							<div class="sidebar-content">
								Container 3
							</div>
						</div>

						<div class="sidebar-item sticky-top">
							<div class="sidebar-content">
								Container 4
							</div>
						</div>

					</div>
				</div>
			</div>
		</div>
	</article>
</body>

If we convert the sidebar section into a flexbox with items arranged in a column with space-between, you can create a more visually interesting sidebar:

body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
}



.content-section {
	background: lavender;
	height: 3000px;
	min-height: 100vh;
	padding: 1em;
}

.sidebar-section {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	height: 100%;
}

.sidebar-content {
	background: cornflowerblue;
	padding: 1em;
	color: #ffffff;
}

When visiting HTML file in the web browser, we should observe a content section and multiple sidebar items with space between them. When scrolling down, you should observe the sidebar items becoming sticky to the top of the screen.

Output:

See the Pen Scenarios – 1 :  Sticky Sidebar and Multiple Items by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

Scenarios – 2 :  Stacking All Sidebar Items

A common feature request is to keep all the sidebar items “stacked” visually on the screen.

This would require knowing the height of each sidebar item and offsetting the sticky top value. Instead of the default top: 0 provided by sticky-top class, you would provide the sum of the height of the preceding sidebar items.

Since the number of sidebar items and their height is known in this demonstration, you can apply the offset to each sidebar item using nth-child:

body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
}



.content-section {
	background: lavender;
	height: 3000px;
	min-height: 100vh;
	padding: 1em;
}

.sidebar-section {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	height: 100%;
}

.sidebar-content {
	background: cornflowerblue;
	padding: 1em;
	color: #ffffff;
}


.sidebar-item:nth-child(2) {
	top: 3.5em;
}

.sidebar-item:nth-child(3) {
	top: 7em;
}

.sidebar-item:nth-child(4) {
	top: 10.5em;
}

When visiting HTML file in the web browser, we should observe a content section and multiple sidebar items with space between them. When scrolling down, we should observe the sidebar items stacking.

However, this is restricted to the scenario of knowing that your sidebar contains 4 sidebar items that are each 3.5em tall. Any additional complexity will be stressing the limitations of Pure CSS and your time may be better suited using a JavaScript solution.

See the Pen Scenarios – 2 :  Stacking All Sidebar Items by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

Scenarios – 3 :  Pushing Sidebar Items Offscreen

Continuing to build off the previous example, a less restricted alternative may be to “push” the previous sidebar item off the screen.

First, we should remove the previous experiments with nth-child. This new configuration will use flex-grow property for the .sidebar-item:

body {
	font-size: 16px;
	font-family: 'Poppins', sans-serif;
}



.content-section {
	background: lavender;
	height: 3000px;
	min-height: 100vh;
	padding: 1em;
}

.sidebar-section {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	height: 100%;
}

.sidebar-content {
	background: cornflowerblue;
	padding: 1em;
	color: #ffffff;
}

.sidebar-item {
	flex-grow: 1;
}


Now, move the sticky-top class from the sidebar-item element to the sidebar-content element:

<body>
	<article>
		<div class="container-fluid">
			<div class="row">
				<div class="col">
					<div class="title-section">
						<h1>Stacking Sticky Sidebars with Bootstrap</h1>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-7">
					<div class="content-section">
						Content Section
					</div>
				</div>
				<div class="col-5">
					<div class="sidebar-section">

						<div class="sidebar-item">
							<div class="sidebar-content sticky-top">
								Container 1
							</div>
						</div>

						<div class="sidebar-item">
							<div class="sidebar-content sticky-top">
								Container 2
							</div>
						</div>

						<div class="sidebar-item">
							<div class="sidebar-content sticky-top">
								Container 3
							</div>
						</div>

						<div class="sidebar-item">
							<div class="sidebar-content sticky-top">
								Container 4
							</div>
						</div>

					</div>

				</div>
			</div>
		</div>
	</article>
</body>

When visiting HTML file in the web browser, we should observe a content section and multiple sidebar items. When scrolling down, you should observe a “stacking” behavior as sidebar items “push” the previous sidebar items.

See the Pen Scenarios – 3 :  Pushing Sidebar Items Offscreen by Sunil Pradhan (@Sunil_Pradhan) on CodePen.

Conclusion

In this tutorial, you learned about the CSS property position: sticky and how it can be used for sidebars in your layouts for web design.

Further Reading

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Similar articles you may like

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.

Add comment

Stay Updated

Want to be notified when our article is published? Enter your email address below to be the first to know.

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.