Search code examples
htmlcsscss-positionz-index

Setting Z-index for a absolute position nested inside of a fixed container


I have a header tag that I set a fixed property to. Inside that header tag, I have a nav tag that I set to be absolute positioned. The issue I am having is I can't seem to pull the header tag to sit in front of the nav tag. Even with setting the header tag to a z-index of 1000 and the nav tag to a z-index of 500. Is what I am trying to do possible?

<header> <-- fixed position
   <section> logo here </section>
   <nav data-nav="main-navigation">   <-- absolute position
      <ul>
         <li><a href="#" id="selected">HOME <div></div></a></li>
         <li><a href="#">ABOUT US</a></li>
         <li><a href="#">SERVICES</a></li>
         <li><a href="#">GALLERIES</a></li>
         <li><a href="#">BLOG</a></li>
         <li><a href="#">CONTACT US</a></li>
      </ul>
     </nav>
  </header>

Here is a code pen to show what I am trying to do

CSS position codepen


Solution

  • With position: fixed, the child element can't sit behind its parent. The trick is to use a pseudo-element on the parent, which will act as a sibling to the child.

    With what you've described, the text will be behind the header color.

    header{
      position: fixed;
      width: 100%;
      height: 100px;
    }
    
    header::before {
      content: '';
      position: absolute;
      height: 100%;
      z-index: 100;
      width: 100%;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: red;
    }
    
    header nav{
      position: fixed;
      background-color: blue;
      width: 50%;
      height: 50vh;
      top:0;
    }
    
    header ul{
      list-style:none;
    }
    
    header a{
      color: #fff;
    }
    <header>
      <h1>HELLO</h1>
      
      <nav>
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </header>

    If you want the text to show up on top of the red, you would need to use a pseudo-element on nav instead. If you don't need position: fixed, you can use any other positioning on the parent combined with a negative z-index on the child:

    header{
      position: absolute;
      width: 100%;
      background-color: red;
      height: 100px;
    }
    
    header nav{
      position: absolute;
      background-color: blue;
      width: 50%;
      height: 50vh;
      top:0;
      z-index: -1;
    }
    
    header ul{
      list-style:none;
    }
    
    header a{
      color: #fff;
    }
    <header>
      <h1>HELLO</h1>
      
      <nav>
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </header>