0

I want a drop down nav bar that (with the header) covers the entire viewport. I do not want the content behind the nav drop down to scroll behind the drop down.

I've achieved this by using position: fixed on the header and nav elements. And when my menu button is clicked the body has overflow: hidden applied.

Problem is, on very small viewports the bottom nav list items fall outside the viewport and I can't scroll down to see/click them.

Here's my code.

header {
    height: 60px;
    background-color: green;
}

body.nav-shown {
      overflow: hidden;
}

body.nav-shown header {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
}

body.nav-shown nav {
      position: fixed;
      top: 60px;
      left: 0;
      right: 0;
      min-height: calc(100vh - 60px);
      background-color: black;
      color: white;
      font-size: 30px;
      line-height: 3em;
      overflow: scroll;
}
<body class="nav-shown">

<header>
    
    <button class="nav-button">Menu</button>

    <nav>
        <ul>
      <li>Link1</li>
      <li>Link2</li>
      <li>Link3</li>
      <li>Link4</li>
      <li>Link5</li>
      <li>Link6</li>
      <li>Link7</li>
       <li>Link8</li>
      <li>Link9</li>
   </ul>
    </nav>

</header>
user2991837
  • 626
  • 1
  • 8
  • 17
  • You only set a `min-height`, meaning your nav element is still allowed to grow larger, if the amount of content it contains demands that. You either want to set a `max-height` here, or, if you alway want the element to extend to the bottom of the viewport, `height`. – CBroe May 15 '23 at 12:30
  • Exactly what @CBroe said. Also consider using CSS media queries to set a different height for different screen sizes. – Al John May 15 '23 at 12:32

4 Answers4

0

Fixed section should be set with width, height and top, bottom properties, otherwise it won't recognise its size and position.

In this case you can use max-height: 100%; to the nav.

header {
  height: 60px;
  background-color: green;
}

body.nav-shown {
  overflow: hidden;
}

body.nav-shown header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

body.nav-shown nav {
  position: fixed;
  top: 60px;
  left: 0;
  right: 0;
  min-height: calc(100vh - 60px);
  max-height: 100%;
  background-color: black;
  color: white;
  font-size: 30px;
  line-height: 3em;
  overflow: scroll;
}
<body class="nav-shown">
  <header>
    <button class="nav-button">Menu</button>
    <nav>
      <ul>
        <li>Link1</li>
        <li>Link2</li>
        <li>Link3</li>
        <li>Link4</li>
        <li>Link5</li>
        <li>Link6</li>
        <li>Link7</li>
        <li>Link8</li>
        <li>Link9</li>
      </ul>
    </nav>
  </header>
</body>
Madan Bhandari
  • 2,094
  • 2
  • 26
  • 46
0

You can give overflow: auto on the header element and set min-height to header element instead of nav element. Here is the updated code. Try that:-

 header {
        height: 60px;
        background-color: green;
    }

    body.nav-shown {
        overflow: hidden;
    }

    body.nav-shown header {
          position: fixed;
          top: 0;
          left: 0;
          right: 0;
          overflow: auto;
          min-height: calc(100vh - 60px);
    }



    body.nav-shown nav {
         position: absolute;
          top: 60px;
          left: 0;
          right: 0;
          background-color: black;
          color: white;
          font-size: 30px;
          line-height: 3em;
    }
    <body class="nav-shown">

    <header>
        
        <button class="nav-button">Menu</button>


        <nav>
            <ul>
          <li>Link1</li>
          <li>Link2</li>
          <li>Link3</li>
          <li>Link4</li>
          <li>Link5</li>
          <li>Link6</li>
          <li>Link7</li>
           <li>Link8</li>
          <li>Link9</li>
       </ul>
        </nav>


    </header>

    </body>
Developer
  • 1,297
  • 1
  • 4
  • 15
0

What I've ended up doing is:

similar to this question: Hide all elements except one div for print view

On click I am setting display: none to everything on the page (I've wrapped everything in a div), apart from the header. This removes the problem of content scrolling behind the nav, because there is nothing to scroll.

Then I've set the header and nav to position: absolute so that on small viewports the user can scroll down to the last link in the nav. This removes issues with fixed positioning not allowing scrolling.

user2991837
  • 626
  • 1
  • 8
  • 17
0

header {
    height: 60px;
    background-color: green;
}

body.nav-shown {
      overflow: hidden;
}

body.nav-shown header {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
}

body.nav-shown nav {
      position: fixed;
      top: 60px;
      left: 0;
      right: 0;
      height: 100%;
      min-height: calc(100vh - 60px);
      background-color: black;
      color: white;
      font-size: 30px;
      line-height: 3em;
      overflow: scroll;
}
<body class="nav-shown">

<header>
    
    <button class="nav-button">Menu</button>

    <nav>
        <ul>
      <li>Link1</li>
      <li>Link2</li>
      <li>Link3</li>
      <li>Link4</li>
      <li>Link5</li>
      <li>Link6</li>
      <li>Link7</li>
       <li>Link8</li>
      <li>Link9</li>
   </ul>
    </nav>

</header>

height 100% in here, fixes this

body.nav-shown nav {
 position: fixed;
 top: 60px;
 left: 0;
 right: 0;
 height: 100%;   
 min-height: calc(100vh - 60px);
 background-color: black;
 color: white;
 font-size: 30px;
 line-height: 3em;

}

Blackwolf
  • 93
  • 1
  • 12