Search code examples
htmlcssheadercss-positionsticky

CSS position sticky doesn't work properly when element is inside another


i'm trying to make an element stick to the top, but it doesn't work when it's inside another div. The header div doesn't have any style by itself.

nav {
    height: 50px;
    background: lightgreen;
    position: sticky;
    top: 0;
}

main {
    height: 200vh;
    background: linear-gradient(180deg, black 0%, white 100%);
}

aside {
    height: 30px;
    background: red;
}
<header>
  <aside></aside>
  <nav></nav>
</header>
<main></main>

If i apply sticky on the header element it works, but it will also drag the aside element, i want only the nav element to be sticky:

header {
    position: sticky;
    top: 0;
}

nav {
    height: 50px;
    background: lightgreen;
}

main {
    height: 200vh;
    background: linear-gradient(180deg, black 0%, white 100%);
}

aside {
    height: 25px;
    background: red;
}
<header>
    <aside></aside>
    <nav></nav>
</header>
<main></main>

This limits a lot what i can do with sticky property if it's intended. The only solution i've found is to remove the header element and keep all elements inside body.


Solution

  • if your aside will always have a fixed height use negative top value and make the parent container sticky:

    nav {
      height: 50px;
      background: lightgreen;
    }
    
    header {
      position: sticky;
      top: -30px;
    }
    
    main {
      height: 200vh;
      background: linear-gradient(180deg, black 0%, white 100%);
    }
    
    aside {
      height: 30px;
      background: red;
    }
    <header>
      <aside></aside>
      <nav></nav>
    </header>
    <main></main>