Welcome to a tutorial and examples on how to create a very simple sticky menu with HTML and CSS. So you need to “fix” a navigation menu on the web page, and make it follow along as the user scrolls?
We can create a simple sticky menu by using position: sticky
, for example:
<nav style="position:sticky; top:0; left:0;">
<a href="URL">ITEM</a>
<a href="URL">ITEM</a>
</nav>
That covers the quick basics, but how can we improve on it? Let us walk through detailed examples in this guide – Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TLDR – QUICK SLIDES
Fullscreen Mode – Click Here
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
HTML CSS STICKY MENU
All right, let us now get into the detailed examples of creating a sticky menu using HTML CSS only.
EXAMPLE 1) TOP/BOTTOM STICKY MENU
1A) THE HTML
<!-- (A) HEADER -->
<header id="head">MY SITE</header>
<!-- (B) STICKY MENU -->
<nav id="menu">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<!-- (C) CONTENTS -->
<main id="main">
START <div style="height:2000px"></div> END
</main>
This should be pretty self-explanatory. Just create a <nav id="menu">
, and sandwich the <a>
links inside.
1B) THE CSS
/* (A) STICKY MENU */
#menu {
/* (A1) STICK TO TOP ON SCROLL */
position: sticky; top: 0; left: 0;
/* (A2) LAYOUT + BACKGROUND */
display: flex;
background: #2c2c2c;
}
/* (B) MENU ITEMS */
#menu a {
color: #fff;
text-decoration: none;
padding: 10px;
}
#menu a:hover { background: #691717; }
As in the introduction above:
position: sticky; top: 0; left: 0;
is all it takes to create a sticky menu.- Cosmetics for the menu items.
P.S. Check out the hamburger and dropdown menu links below if you are interested in “improving” this simple sticky menu.
1C) STICK TO BOTTOM
- Change the position to bottom –
position: sticky; bottom: 0; left: 0;
. - Make sure that the
<nav>
menu is placed below the<main>
content.
EXAMPLE 2) SIDE STICKY MENU
2A) THE HTML
<!-- (A) STICKY MENU -->
<nav id="menu">
<a href="#">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
</nav>
<!-- (B) CONTENTS -->
<main id="main">
TOP <div style="height:2000px"></div> END
</main>
Menu to the left, content to the right.
2B) THE CSS
/* (A) TWO-COLUMN LAYOUT */
body {
display: flex;
padding: 0; margin: 0;
}
#main { flex-grow: 1; }
/* (B) STICKY MENU */
#menu {
/* (B1) STICK TO TOP ON SCROLL */
position: sticky; top: 0; left: 0;
/* (B2) LAYOUT + BACKGROUND */
height: 100vh;
background: #2c2c2c;
}
/* (C) MENU ITEMS */
#menu a {
display: block; width: 100%;
color: #fff;
text-decoration: none;
padding: 10px;
}
#menu a:hover { background: #691717; }
- Setting
display: flex
on the<body>
will automatically lay the menu and content in a left-right manner. - Same old “stick the menu when the user scrolls down”.
- Lay the menu items out in a single column.
P.S. If you are working with a complex menu, see the collapsible and tree menu links below.
2C) HEIGHT PROBLEM
The menu is fixed to height: 100vh
. There will be a problem if the menu items exceed the height of the window.
- Possible fix 1 – Add scrollbars with
menu { overflow: auto }
, but you are going to get multiple scrollbars on the page. - Possible fix 2 – Use
min-height: 100vh
instead. Allow the menu to grow, but this will affect the sticky mechanism.
2D) SMALL SCREEN PROBLEM
The design is not great on portrait mode small screens. The side menu will leave very little space for the main content area. A possible fix is to adopt a different design on small screens. Add toggle buttons to open/close the menu:
<nav id="menu">
<!-- (RES) TOGGLE BUTTON -->
<button class="tog" onclick="document.getElementById('menu').classList.remove('show')">X</button>
</nav>
<main id="main">
<!-- (RES) TOGGLE BUTTON -->
<button class="tog" onclick="document.getElementById('menu').classList.add('show')">☰</button>
</main>
Hide the menu by default, and show it in full screen when toggled.
/* (RES) OPTIONAL RESPONSIVE SUPPORT */
/* HIDE TOGGLE BUTTON ON BIG SCREENS */
.tog { display: none; }
@media screen AND (max-width: 640px) {
/* SHOW TOGGLE BUTTON ON SMALL SCREENS */
.tog { display: block; }
/* SHOW/HIDE MENU */
#menu { display: none; }
#menu.show {
display: block;
position: fixed; top:0; left: 0;
width: 100vw; min-height: 100vh;
}
}
EXTRA BITS & LINKS
That’s all for the code, and here are a few more extras that may be useful to you.
HATERS GONNA HATE
Congratulations to the folks with only a few menu items to deal with – This tutorial will serve you well with only a few small changes.
To the people who are thinking “I can create a complex menu with a very simple tutorial” – Your expectations are wrong. Follow up with the hamburger, dropdown, or tree menu. Don’t need to bang on the keyboard, it will not solve your problems even if you blame someone else.
LINKS & REFERENCES
- CSS Position – MDN
- Responsive Hamburger Menu – Code Boxx
- Responsive Dropdown Menu – Code Boxx
- Collapsible Tree Menu – Code Boxx
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to create a better website, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!