I have now been scratching my head a long time as to how to make a sticky navbar on top of the content of the page.
I have a webpage that contains a header, a main block, and a footer.
I want the main block to have a navbar to navigate easily among the different sections of its content. This navbar needs to be always accessible to the user while they are navigating inside the main block, which is why I want to make it sticky
.
What makes it difficult though, is that I want the navbar to be on top of the content of the main block, to allow each section of the main block to have a background-color that extends to the full width of the page.
In the following example, I recreated something approaching what I want, except that each main content block needs to extend to the full width of the page.
How would I go about this?
.header,
.footer {
background-color: silver;
height: 40vh;
}
.main {
display: flex;
}
.nav > .navcontent {
position: sticky;
top: 0;
}
.content > .block {
height: 80vh;
padding-left: 20%;
padding-right: 20%;
}
.content > .block.-b1 {
background-color: aqua;
}
.content > .block.-b2 {
background-color: teal;
}
.content > .block.-b3 {
background-color: blue;
}
<header class="header">
<h1>Header</h1>
</header>
<main class="main">
<div class="content">
<div class="block -b1">
<h1>My content</h1>
<p>Integer interdum varius diam. Nam aliquam velit a pede. Vivamus dictum nulla et wisi. Vestibulum a massa. Donec vulputate nibh vitae risus dictum varius. Nunc suscipit, nunc nec facilisis convallis, lacus ligula bibendum nulla, ac sollicitudin sapien nisl fermentum velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam commodo dui ut augue molestie scelerisque. Sed aliquet rhoncus tortor. Fusce laoreet, turpis a facilisis tristique, leo mauris accumsan tellus, vitae ornare lacus pede sit amet purus. Sed dignissim velit vitae ligula. Sed sit amet diam sit amet arcu luctus ullamcorper.</p>
</div>
<div class="block -b2">
<p>Integer interdum varius diam. Nam aliquam velit a pede. Vivamus dictum nulla et wisi. Vestibulum a massa. Donec vulputate nibh vitae risus dictum varius. Nunc suscipit, nunc nec facilisis convallis, lacus ligula bibendum nulla, ac sollicitudin sapien nisl fermentum velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam commodo dui ut augue molestie scelerisque. Sed aliquet rhoncus tortor. Fusce laoreet, turpis a facilisis tristique, leo mauris accumsan tellus, vitae ornare lacus pede sit amet purus. Sed dignissim velit vitae ligula. Sed sit amet diam sit amet arcu luctus ullamcorper.</p>
</div>
<div class="block -b3">
<p>Integer interdum varius diam. Nam aliquam velit a pede. Vivamus dictum nulla et wisi. Vestibulum a massa. Donec vulputate nibh vitae risus dictum varius. Nunc suscipit, nunc nec facilisis convallis, lacus ligula bibendum nulla, ac sollicitudin sapien nisl fermentum velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam commodo dui ut augue molestie scelerisque. Sed aliquet rhoncus tortor. Fusce laoreet, turpis a facilisis tristique, leo mauris accumsan tellus, vitae ornare lacus pede sit amet purus. Sed dignissim velit vitae ligula. Sed sit amet diam sit amet arcu luctus ullamcorper.</p>
</div>
</div>
<nav class="nav">
<ul class="navcontent">
<li>Link 1
<li>Link 2
<li>Link 3
</ul>
</nav>
</main>
<footer class="footer">
<h1>Footer</h1>
</footer>
2
Answers
One way to do this, would be to make.content
go over the full width (flex: 0 0 100%;
), and move the navigation that gets "pushed aside" by that, to the left again by its own width, usingtransform: translateX(-100%);
That approach left whitespace on the right, so slightly modified:
.navcontent get a fixed width (which you said you wanted to go with anyway), via
flex: 0 0 3em;
And the full-width .content gets an additional
margin-right: -3em;
to counter the navigation’s width.To solve that, I would probably use
display: grid
, and define overlapping areas for.content
and.nav
usinggrid-template-columns
.That is likely the most flexible solution regarding the HTML structure and styling.
And I would use a variable for the
width
of the navigation so that you could also use it for the padding on the right of your content.That variable then could be changed with a media query depending on the screen size.