Jump to content

TopNav and fixed SideNav scrolling problem


SSteven

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.

Link to comment
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.

Link to comment
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>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...