Jump to content
SSteven

TopNav and fixed SideNav scrolling problem

Recommended Posts

The following webpage authored by me contains a  TopNav and fixed SideNav.

The TopNav isn't fixed. So it can scroll. Only the SideNav is fixed at the left.

Both Navbars are created using flexboxes.

Here's the key CSS:

      /* Top navigation bar */
      .topnav
      {
        display: flex;
        background-color: #777;		/* gray */
      }

      /* Side navigation bar */
      .sdnav
      {
        display: flex;
        flex-direction: column;

        width: 200px;
        height: 100%;
        position: fixed;
        overflow: auto;	
        background-color: #f1f1f1;		/* light gray */
      }

And here's the key HTML:

  <body>
    <!-- Top Navigation Bar -->
    <div class="topnav">
      <a href="#">Home</a>
      <a href="#" class="active">News</a>
      <a href="#">Contact</a>
      <a href="#">About</a>
    </div>

    <!-- Side Navigation Bar -->
    <div class="sdnav">
      <a href="#">What</a>
      <a href="#" class="active">Where</a>
      <a href="#">When</a>
      <a href="#">How</a>
    </div>

    <div class="main">
      ...
    </div>
</body>

A problem occurs when I scroll down. This causes the TopNav to move off the top of the screen (since it isn't fixed). And here's the problem: A gap at the top of the SideNav then appears.

Basically the problem occurs since:

1) The TopNav isn't fixed whereas the SideNav is fixed.

2) The SideNav occurs in the markup below the TopNav.

One way to solve this problem is to make the TopNav fixed. Then a gap would obviously not appear above the SideNav, since the TopNav couldn't disappear in the first place.

Is there any other solution using just CSS?

Note: Both Navbars are responsive. The responsive part is working fine. It's just the gap while scrolling that's the problem.

Thanks.

Share this post


Link to post
Share on other sites

If you want a solution without JS you can set the position to "sticky" instead of fixed. The only drawback is that the sidebar can't be the full height of the screen, but I think it still looks pretty good.

Share this post


Link to post
Share on other sites

Why not make it fixed to top with top: 0; and place home link at top of side-nav, use position: relative; z-index: 100; on top-nav, forcing it to overlap and hide home link in side-nav, then there will always be a viewable home link.

Share this post


Link to post
Share on other sites

As Ingolme said, I modified the postion to sticky with top: 0 and the gap disappears when you scroll down

/* Side navigation bar */
.sdnav {
  display: flex;
  flex-direction: column;

  width: 200px;
  height: 100%;
  position: sticky;
  top: 0;
  overflow: auto;
  background-color: #f1f1f1; /* light gray */
}

 

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Portfolio</title>
    <style>
        * {
  box-sizing: border-box;
}

body {
  margin: 0;
}

/* Top navigation bar */
.topnav {
  display: flex;
  background-color: #777; /* gray */
}

/* Top Navigation bar links */
.topnav a {
  padding: 14px 20px;
  color: white;
  text-decoration: none;
  text-align: center;
}

/* Change Top Navigation bar link color on hover */
.topnav a:hover:not(.active) {
  background-color: #ddd; /* light gray */
  color: black;
}

/* Top Navigation bar's active link color */
.topnav a.active {
  background-color: #4caf50; /* green */
}

/* Side navigation bar */
.sdnav {
  display: flex;
  flex-direction: column;

  width: 200px;
  height: 100%;
  position: sticky;
  top: 0;
  overflow: auto;
  background-color: #f1f1f1; /* light gray */
}

/* Side navigation bar links */
.sdnav a {
  padding: 14px 20px;
  color: black;
  text-decoration: none;
  text-align: left;
}

/* Change Side navigation bar link color on hover */
.sdnav a:hover:not(.active) {
  background-color: #555; /* gray */
  color: white;
}

/* Side Navigation bar's active link color */
.sdnav a.active {
  background-color: aquamarine;
}

.main {
  margin-left: 200px;
  padding: 10px;
  height: 1000px;
}

/* Stack the sdnav horizontally when the screen size
         is 768px or less */
@media screen and (max-width: 768px) {
  .sdnav {
    flex-direction: row;

    width: 100%;
    height: auto;
    position: relative;
  }

  .sdnav a {
    width: auto;
    text-align: center;
  }

  .main {
    margin-left: 0;
    padding: 0 16px;
  }
}

/* Stack the sdnav vertically at the center,
         when the screen size is 600px or less */
@media screen and (max-width: 600px) {
  .sdnav {
    flex-direction: column;
  }

  .sdnav a {
    width: 100%;
  }
}

/* Stack the topnav vertically when the screen size
         is 600px or less */
@media screen and (max-width: 600px) {
  .topnav {
    flex-direction: column;
  }
}

    </style>
        
      
  </head>

  <body>
  <!-- Top Navigation Bar -->
<div class="topnav">
  <a href="#">Home</a>
  <a href="#" class="active">News</a>
  <a href="#">Contact</a>
  <a href="#">About</a>
</div>

<!-- Side Navigation Bar -->
<div class="sdnav">
  <a href="#">What</a>
  <a href="#" class="active">Where</a>
  <a href="#">When</a>
  <a href="#">How</a>
</div>

<div class="main">
      <h1>
        Responsive Top Navigation Bar AND
        Fixed Full-height Responsive Side Navigation Bar
        - using <span style="color: red;">flexbox</span>
      </h1>

      <p>
        This example uses 3 media queries:
      </p>

      <ol>
        <li>
          The first stacks the SideNav <em>horizontally</em>,
          when the screen size is<strong>768px</strong> or less.
        </li>

        <li>
          The second stacks the SideNav <em>vertically</em>,
          at the center when the screen size is <strong>600px</strong> 
          or less.
        </li>

        <li>
          The third stacks the TopNav <em>vertically</em>,
          at the center when the screen size is <strong>600px</strong> 
          or less.
        </li>
      </ol>

      <h4>
        Try to scroll this area, and see how the sidenav 
        sticks to the page.
      </h4>

      <h4>Resize the browser window to see the effect.</h4>

      <p>
        <strong>Note</strong>: When the page is scrolled down, a gap will
        be seen at the top of the sidebar. This occurs, since the SideNav 
        is located <em>below</em> the TopNav in the markup.
        <br>
        If the SideNav is located <em>above</em> the TopNav in the markup,
        it would appear <em>on top of</em> the TopNav.
        <br>
        To solve this problem, keep the TopNav (and anything above it) fixed.
      </p>

      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
      <p>Some text..</p>
    </div>

  </body>
</html>

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...