How to create a sidebar that’s sticky but also scrolls

By

Learn how to build a sidebar that stays sticky yet scrolls on short screens using CSS position sticky, top 0, height 100vh, and overflow-y auto, or Tailwind.

~~~

To make a sidebar fixed but also accommodate screens that are not tall enough to contain the entire sidebar, use this CSS:

.sidebar {
  position: sticky;
  top: 0;
  height: 100vh; 
  overflow-y: auto;
}

Using Tailwind CSS:

<div class='sticky top-0 h-screen overflow-y-auto'>
...
</div>

The problem this solves

A sidebar with lots of links has two competing needs.

You want it to stay visible while the main content scrolls. That’s what position: sticky with top: 0 does: the sidebar scrolls normally until it reaches the top of the viewport, then it stays pinned there.

But on a laptop screen, a long sidebar might be taller than the viewport. If it just sticks, the links at the bottom become unreachable. You can never scroll to them.

How the four properties work together

Each line has a job:

position: sticky makes the element stick within its parent as you scroll.

top: 0 sets where it sticks: flush against the top of the viewport.

height: 100vh caps the sidebar at exactly one viewport height, so it never extends below the visible area.

overflow-y: auto is the trick that makes it work on short screens. If the sidebar content is taller than the viewport, the sidebar gets its own scrollbar. You scroll the page to move the content, and you scroll inside the sidebar to reach its bottom links.

When the content fits, auto shows no scrollbar at all, so tall screens are unaffected.

Why isn’t my sidebar sticking?

The most common failure happens in flex layouts, which is exactly where sidebars live.

By default, flex items stretch to the height of their container. If your sidebar is as tall as the whole page, there’s no room for it to move, so sticky does nothing. Setting height: 100vh fixes this, which is another reason it’s in the snippet. You can also use align-self: flex-start.

The other thing to check: no ancestor between the sidebar and the page can have overflow: hidden. That changes which container the sidebar sticks inside, and the effect breaks. If sticky stops working after a refactor, walk up the tree and look at the overflow values.

Notice we used sticky instead of position: fixed. Fixed removes the element from the layout, so you’d have to compensate with margins on the content. Sticky keeps the sidebar in the normal flow, and the layout keeps working.

Tagged: CSS · All topics
~~~

Related posts about css: