Creating Sticky Elements with CSS: Sticky Headers, Footers, and Sidebars

Emelogu Chinonso Christian
LearnFactory Nigeria
10 min readMay 25, 2023

Website headers that stay in place when a user scrolls have become a very popular design element. They allow the user to easily access the navigation without the need to scroll up each time they want to choose a different page or option.

Elements with this functionality are often called “sticky” because they stick with the user, remaining visible as they move through the website. When a user first arrives at the website, elements will be in their starting position, but then the sticky header will remain in the same place.

Since navigation is one of the most important elements of a website, taking this approach helps make navigation more accessible. Having a navigation that stays in place allows for an easy flow for the user as they move through the website content, which is extremely important.

What is a header and a sticky header?

A sticky header is a menu or navigation bar that stays at the top of the page no matter where you scroll. In other words, a “fixed” header. This feature is useful for users because it enables them to easily find their way out of a page no matter where they are. Without easy access to the navigational panel, the user experience can become stressful. Like most things, when a problem is solved well, the problem and solution both go unnoticed. That’s what we want! Personally, I’ve left websites solely because simple navigation options were not available, and in some cases, I’d even rather call the company than deal with their website.

Sticky positioning

Sticky positioning can be thought of as a hybrid of relative and fixed positioning when its nearest scrolling ancestor is the viewport. A stickily positioned element is treated as relatively positioned until it crosses a specified threshold, at which point it is treated as fixed until it reaches the boundary of its parent. For example:

#one { 
position: sticky;
top: 10px;
}

The above CSS rule would position the element with id one relatively until the viewport was scrolled such that the element would be less than 10 pixels from the top. Beyond that threshold, the element would be fixed to 10 pixels from the top.

A common use for sticky positioning is for the headings in an alphabetized list. The “B” heading will appear just below the items that begin with “A” until they are scrolled offscreen. Rather than sliding offscreen with the rest of the content, the “B” heading will then remain fixed to the top of the viewport until all the “B” items have scrolled offscreen, at which point it will be covered up by the “C” heading, and so on.

You must specify a threshold with at least one of the top, right, bottom, or left for sticky positioning to behave as expected. Otherwise, it will be indistinguishable from relative positioning.

Start your HTML DOCUMENT

If you don’t already have an HTML document thrown together, don’t forget to have the proper <!DOCTYPE html> tag as well as <head> and <body> tags. Best practice tip: name the file “index.html” and put all the new files you will be creating into one folder, otherwise there will be problems with linking.

1. Use a <div> inside a <div>, inside another <div> tag. The inside most <div> is for content, and the encompassing <div> is the content’s container.

2. Give the content’s parent <div> a class called “header”.

3. Add some text into the inside most <div> so you can watch as it follows your scroll.

The <div> tags are a standard element to use and easy to use for beginners. To learn more about <div> tags, W3Schools is a great resource.

<!DOCTYPE html> 
<head>
<title>sticky header</title>
</head>
<body>
<div>
<div class=”header”>
<div>HEADER CONTENT</div>
</div>
</div>
</body>
</html>

Start your CSS file

A CSS file doesn’t need a particular setup other than referencing the proper element and adding styles to the corresponding elements. Best practice tip: name the file “main.css”.

1. Refer to the <div> class named “header” and add attributes and values shown below.

2. Add a couple of attributes and values to the body that will help you see that the header is sticking. The most important part is adding the “position: fixed;” attribute and value. That’s what keeps that <div> stuck to the top of the window, thus creating a sticky header. Adding a big number to the body’s height will allow for scrolling so you can test the functionality of the sticky header. I picked 2000px, yours can be just over 800px. Whatever will give you a scrolling capability in your window will do just fine.

body { 
height: 2000px;
margin: 0;
background:
radial-gradient(circle, transparent 20%, slategray 20%, slategray 80%,
transparent 80%, transparent),
radial-gradient(circle, transparent 20%, slategray 20%, slategray 80%,
transparent 80%, transparent) 50px 50px,
linear-gradient(#A8B1BB 8px, transparent 8px) 0 -4px,
linear-gradient(90deg, #A8B1BB 8px, transparent 8px) -4px 0;
background-color: slategray;
background-size:100px 100px, 100px 100px, 50px 50px, 50px 50px;
}
.header {
font-size: 30px;
color: #FFFFFF;
border: 1px dashed orange;
position: fixed;
height: 150px;
width: 100%;
text-align: center;
}

3. Link to the CSS file from the HTML file using the following code inside the <head> tag:

<link rel="stylesheet" type="text/css" href="main.css">

Sticky CSS elements help create an easy user flow as people move through your website.

What Makes it Sticky?

Fixed positioning is a key component to getting the navigation to stay in place. This fixed position element is positioned relative to the viewport, or the browser window itself. Because the viewport doesn’t change when the site is scrolled, this fixed-positioned element will stay in the same place when the page is scrolled.

How Do We Get the Navigation to Stay in One Place?

Making the navigation sticky could not be easier; it’s just done with CSS styling. It basically looks something like this:

[css] 

.navbar-fixed-top {

position: fixed;

right: 0;

left: 0;

z-index: 999;

}

[/css]

No matter how long your page is, or how many times you scroll up and down, the nav will be “stuck” to the top of the page. A class called .navbar-fixed-top was added to the navigation that creates the placement for the navigation. I added this class to the nav tag. The position is set to fixed and adding left and right positioning ensures that the placement is correct and takes up the full width of the page.

Keep in mind, anytime this class is applied, it will create the fixed position of the element. Most likely this class will only be applied once, otherwise there would be multiple page elements behaving the same way in the same place, creating a jumbled mess.

Another important consideration is the z-index. Because we want the navigation to always be visible, we need to make sure it does not get overlapped by other elements. When we reference the z-index, we are talking about the CSS property that sets the stack order of specific elements. An element with greater stack order is always in front of another element with lower stack order. A value of 999 is a large number, making it a safe bet for the navigation.

Adjust Page Body

Because the navigation is now at a fixed position, it will cover part of the content at the top. There is a simple fix for this. Adding padding to the top of the body will push the page down so then content at the top will not be covered by the header when the user arrives on the page.
You can add padding to the body in your CSS file:

[css]

body {

padding-top: 75px;

}

[/css]

Keep in mind that your padding may be larger or smaller depending on how thick the fixed header is.

How to Create Sticky Footer with CSS

A sticky footer is the footer of the web-page, which sticks to the bottom of the viewport when the content is shorter than the viewport height. This allows us to navigate a website easily and can be created with CSS.

Do not confuse a sticky footer with the “fixed” and “sticky” values of the position property.

Creating a sticky footer is quite easy. In this snippet, we will show some simple methods.

Let’s start with an example where we have negative margins.

Create HTML

  • Use two <div> elements with the following class names: “content” and “push”.
  • Add a <footer> element with the class name “footer”.

<div class=”content”>
<h1>Sticky Footer</h1>
<p>Example</p>
<div class=”push”></div>
</div>
<footer class=”footer”>
Footer
</footer>

Add CSS

  • Specify the height and margin properties for the <html> and <body>elements.
  • Add the padding, min-height, and margin properties to the “content” classs.
  • Set the height property equal to the negative margin.

html,
body {
height: 100%;
margin: 0;
}

.content {
padding: 20px;
min-height: 100%;
margin: 0 auto -50px;
}

.footer,
.push {
height: 50px;s
}

* {
box-sizing: border-box;
}

body {
font: 16px Sans-Serif;
}

h1 {
margin: 0 0 20px 0;
}

p {
margin: 20px 0 0 0;
}

footer {
background: #42A5F5;
color: white;
line-height: 50px;
padding: 0 20px;
}

Let’s see the result of our code.

Example of creating a sticky footer with negative bottom margin:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
html,
body {
height: 100%;
margin: 0;
}
.content {
padding: 20px;
min-height: 100%;
margin: 0 auto -50px;
}
.footer,
.push {
height: 50px;
}
* {
box-sizing: border-box;
}
body {
font: 16px Sans-Serif;
}
h1 {
margin: 0 0 20px 0;
}
p {
margin: 20px 0 0 0;
}
footer {
background: #42A5F5;
color: white;
line-height: 50px;
padding: 0 20px;
}
</style>
</head>
<body>
<div class=”content”>
<h1>Sticky Footer</h1>
<p>Example</p>
<div class=”push”></div>
</div>
<footer class=”footer”>
Footer
</footer>
</body>
</html>

In the example above, we have a negative margin, which is equal to the height of the footer. The “push” class ensures that the negative margin won’t pull the footer up and cover content.

Example of creating a sticky footer with negative top margins on footer:

<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
height: 100%;
margin: 0;
}
.content {
min-height: 100%;
}
.content-inside {
padding: 20px;
padding-bottom: 50px;
}
.footer {
height: 50px;
margin-top: -50px;
}
body {
font: 16px Sans-Serif;
}
h1 {
margin: 0 0 20px 0;
}
p {
margin: 20px 0 0 0;
}
footer {
background: #42A5F5;
color: white;
line-height: 50px;
padding: 0 20px;
}
</style>
</head>
<body>
<div class=”content”>
<div class=”content-inside”>
<h1>Sticky Footer</h1>
<p>Example</p>
</div>
</div>
<footer class=”footer”>
Footer
</footer>
</body>
</html>

Example of creating a sticky footer with the! important rule:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
* {
margin: 0;
}
html,
body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
background-color: #9e9e9e;
margin: 0 auto -142px;
}
.footer,
.push {
height: 142px;
}
.footer {
background-color: #318ccc;
}
</style>
</head>
<body>
<div class=”wrapper”>
<h1>Sticky Footer</h1>
<p>Example</p>
<div class=”push”></div>
</div>
<div class=”footer”>
Footer
</div>
</body>
</html>

The methods presented above require footers with a fixed height. In web design, fixed heights are usually not encouraged as content can change. Whereas using Flexbox for a sticky footer does not require an extra element and allows us to use a varying height footer. Let’s see this method in use!

Example of creating a sticky footer with Flexbox:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
html {
height: 100%;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1 0 auto;
padding: 20px;
}
.footer {
flex-shrink: 0;
padding: 20px;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font: 16px Sans-Serif;
}
h1 {
margin: 0 0 20px 0;
}
p {
margin: 0 0 20px 0;
}
footer {
background: #42A5F5;
color: white;
}
</style>
</head>
<body>
<div class=”content”>
<h1>Sticky Footer with Flexbox</h1>
<p>Example</p>
</div>
<footer class=”footer”>
Footer
</footer>
</body>
</html>

In the example above, we used the flex property set to 1 on the child element that we want to grow to fill the content.

Next, we’ll show one more example where we create a sticky footer with Grid.

Example of creating a sticky footer with Grid:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
html {
height: 100%;
}
body {
min-height: 100%;
display: grid;
grid-template-rows: 1fr auto;
}
.content {
padding: 20px;
}
.footer {
grid-row-start: 2;
grid-row-end: 3;
}
* {

Creating a sticky sidebar with CSS

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, and I’ve spent many hours battling with legacy code trying to debug one. In the past, developers used JavaScript to build this feature, by recalculating the position of the sidebar on the browser’s scroll event. This was complicated to maintain and also costly for performance.

Recently I was delighted to discover that all major desktop browsers (Chrome, Firefox, Edge and Safari) now support the CSS property position: sticky. (Aside from a bug in Chrome with some table elements.) Edge was the final browser to ship support in October 2017 in version 16, which you can check on caniuse.com.

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

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’ll make shorter than the length of the screen, so we can clearly see it moving in our example. We use flex to position them side-by-side, because it’s 2018 and also because I love flex.

Use the following HTML and CSS:

<div class=”wrapper”>
<div class=”main”>
Main content
</div>
<div class=”sidebar”>
Sticky sidebar
</div>
</div>

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

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

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

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

body {
background-color: #ccc;
font-family: sans-serif;
padding: 10px;
}

This gives us two elements that look like this:

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: -webkit-sticky;
position: sticky;
top: 0;
}

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.

--

--