skip to Main Content

I have a fixed vertical <nav> element that has a dynamic width. I want it not to overlap with the <main> element no matter what, even if the screen width is small

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
  box-sizing: border-box;
  margin: 0;
  scroll-behavior: smooth;
}

body {
  display: flex;
}

nav {
  position: fixed;
  display: flex;flex-direction: column;
  flex-wrap: wrap;
  width: 20%;
  min-width: max-content;
  height: 100%;
  padding: 1rem 0.5rem;
  background-color: #5382a1;
  font-family: Tahoma, sans-serif;
}

nav header {
  font-weight: bold;
  color: white;
}

nav ul {
  padding: 0;
}

nav li {
  display: block;
  padding: 0.4rem;
  border: 1px solid white; 
  margin: 0.2rem 0;
  text-align: center;
  border-radius: 3px;
  background-color: white;
  color: hsl(34, 94%, 54%);
}

nav li:hover {
    color: white; background-color: hsl(34, 94%, 54%);
}

nav a {
text-decoration: none;
color: inherit;
}

nav a:hover {
  color: white;
}

main {
  width: 70%;
  min-width: 200px;
  margin: 1rem 1rem 2rem 25%;
}

p {
  margin: 1rem 0;
}
</style>
  </head>
  <body>
    <nav id="navbar">
      <header>Navbar</header>
      <ul>
        <li><a class="nav-link" href="#section-one">Section One</a></li>
        <li><a class="nav-link" href="#section-two">Section Two</a></li>
        <li><a class="nav-link" href="#section-three">Section Three</a></li>
      </ul>
    </nav>
    <main>
<section id="section-one" class="main-section">
        <header>
          <h2>Section One</h2>
        </header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
<section id="section-two" class="main-section">
        <header>
          <h2>Section Two</h2>
        </header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
<section id="section-three">
        <header>
          <h2>Section Three</h2>
        </header>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
</main>
</body>
</html>

You don’t see any overlap in the code snippet above, but that’s because the width is big enough. If you shrink it roughly to the size of a smartphone, you can start to see the issue

You may notice that <body> has a display: flex property, but it doesn’t help since the <nav> is fixed (so any flex behavior doesn’t apply to it). However, it may give you a better idea of what I try to achieve here

I could hypothetically do something like this

main {
  width: calc(100% - nav.width);
  padding: 1rem;
}

but the problem is you can’t reference variables in the calc() function

I also tried this

nav {
  width: 20vw;
}

main {
  width: 80vw;
}

What would you recommend to avoid overlap of a fixed dynamically-sized vertical navbar with the main content without the use of JS?

I came across this similar question, but none of the answers proved helpful

2

Answers


  1. Chosen as BEST ANSWER

    This kind of works, but it's a bit too hard-coded for my liking. Notice these changes

    nav {
      /* ... */
      width: 20vw;
      min-width: 110px; /* this is hard-coded */
      /* ... */
    }
    
    main {
      width: 80vw;
      min-width: 200px;
      padding: 0 1rem;
      margin: 1rem 1rem 2rem max(20vw, 110px);
    }
    

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
    * {
      box-sizing: border-box;
      margin: 0;
      scroll-behavior: smooth;
    }
    
    body {
      display: flex;
    }
    
    nav {
      position: fixed;
      display: flex;flex-direction: column;
      flex-wrap: wrap;
      width: 20vw;
      min-width: 110px;
      height: 100%;
      padding: 1rem 0.5rem;
      background-color: #5382a1;
      font-family: Tahoma, sans-serif;
    }
    
    nav header {
      font-weight: bold;
      color: white;
    }
    
    nav ul {
      padding: 0;
    }
    
    nav li {
      display: block;
      padding: 0.4rem;
      border: 1px solid white; 
      margin: 0.2rem 0;
      text-align: center;
      border-radius: 3px;
      background-color: white;
      color: hsl(34, 94%, 54%);
    }
    
    nav li:hover {
        color: white; background-color: hsl(34, 94%, 54%);
    }
    
    nav a {
    text-decoration: none;
    color: inherit;
    }
    
    nav a:hover {
      color: white;
    }
    
    main {
      width: 80vw;
      min-width: 200px;
      padding: 0 1rem;
      margin: 1rem 1rem 2rem max(20vw, 110px);
    }
    
    p {
      margin: 1rem 0;
    }
    </style>
      </head>
      <body>
        <nav id="navbar">
          <header>Navbar</header>
          <ul>
            <li><a class="nav-link" href="#section-one">Section One</a></li>
            <li><a class="nav-link" href="#section-two">Section Two</a></li>
            <li><a class="nav-link" href="#section-three">Section Three</a></li>
          </ul>
        </nav>
        <main>
    <section id="section-one" class="main-section">
            <header>
              <h2>Section One</h2>
            </header>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </section>
    <section id="section-two" class="main-section">
            <header>
              <h2>Section Two</h2>
            </header>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </section>
    <section id="section-three">
            <header>
              <h2>Section Three</h2>
            </header>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </section>
    </main>
    </body>
    </html>


  2. Add parent div with position: fixed and display: flex and remove postion:fixed from nav.

    also, don’t forget to add height: 100% and overflow-y: scroll to main

    * {
      box-sizing: border-box;
      margin: 0;
      scroll-behavior: smooth;
    }
    
    .page {
        position: fixed;
        display: flex;
        height: 100%;
        width: 100%;
    }
    nav {
      /* position: fixed; */
      display: flex;
      flex-direction: column;
      flex-wrap: wrap;
      width: 20%;
      min-width: max-content;
      height: 100%;
      padding: 1rem 0.5rem;
      background-color: #5382a1;
      font-family: Tahoma, sans-serif;
    
      flex: 0 0 auto;
    }
    
    nav header {
      font-weight: bold;
      color: white;
    }
    
    nav ul {
      padding: 0;
    }
    
    nav li {
      display: block;
      padding: 0.4rem;
      border: 1px solid white;
      margin: 0.2rem 0;
      text-align: center;
      border-radius: 3px;
      background-color: white;
      color: hsl(34, 94%, 54%);
    }
    
    nav li:hover {
      color: white;
      background-color: hsl(34, 94%, 54%);
    }
    
    nav a {
      text-decoration: none;
      color: inherit;
    }
    
    nav a:hover {
      color: white;
    }
    
    main {
      /* position: fixed; */
      overflow-y: scroll;
      height: 100%;
      width: 70%;
      min-width: 200px;
      margin: 1rem 1rem 2rem 5%;
    }
    
    p {
      margin: 1rem 0;
    }
    <!DOCTYPE html>
    <html>
    
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
      </head>
    
      <body>
        <div class="page">
          <nav id="navbar">
            <header>Navbar</header>
            <ul>
              <li><a class="nav-link" href="#section-one">Section One</a></li>
              <li><a class="nav-link" href="#section-two">Section Two</a></li>
              <li><a class="nav-link" href="#section-three">Section Three</a></li>
            </ul>
          </nav>
          <main>
            <section id="section-one" class="main-section">
              <header>
                <h2>Section One</h2>
              </header>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </section>
            <section id="section-two" class="main-section">
              <header>
                <h2>Section Two</h2>
              </header>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </section>
            <section id="section-three">
              <header>
                <h2>Section Three</h2>
              </header>
              <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
            </section>
          </main>
        </div>
      </body>
    
    </html>

    Here is the jsfiddle link.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search