skip to Main Content

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


  1. 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, using transform: 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.

    .header,
    .footer {
      background-color: silver;
      height: 40vh;
    }
    
    .main {
      display: flex;
    }
    
    .nav > .navcontent {
      position: sticky;
      top: 0;
      flex: 0 0 3em;
      padding: 0;
    }
    
    .content {
      flex: 0 0 100%;
      margin-right: -3em;
    }
    
    .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>
    Login or Signup to reply.
  2. To solve that, I would probably use display: grid, and define overlapping areas for .content and .nav using grid-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.

    :root {
      --nav-width : 150px;
    }
    
    
    .header,
    .footer {
      background-color: silver;
      height: 40vh;
    }
    
    .main {
      display: grid;
      grid-template-columns: [content-start] 1fr [nav-start] var(--nav-width) [content-end nav-end];
    }
    
    .nav {
      grid-area: nav;
    }
    
    .content {
      grid-area: content;
    }
    
    .nav>.navcontent {
      position: sticky;
      top: 0;
    }
    
    .content>.block {
      min-height: 80vh;
      padding-left: 20%;
      padding-right: calc( 20% + var(--nav-width));
    }
    
    .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">
      <nav class="nav">
        <ul class="navcontent">
          <li>Link 1
          <li>Link 2
          <li>Link 3
        </ul>
      </nav>
      <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>
    </main>
    <footer class="footer">
      <h1>Footer</h1>
    </footer>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search