Search code examples
htmlcsspositioncss-gridsticky

Sticky element stops being sticky when certain height is exceeded


I am experiencing a problem with a sticky header I am trying to implement. I simplified the code for y'all to reproduce:

HTML:

<div class="page">
  <div class="header">
    kkk
  </div>
  
  <div class="nav">
    kkk
  </div>
  
  <div class="main">
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
    <div class="item">kkk</div>
  </div>
</div>

CSS:

.page {
  height: 100vh;
    display: grid;
    grid-template-rows: auto 1fr;
    grid-template-columns: auto;
      grid-template-areas:
        "header header header"
        "nav main main";
}

.header {
  position:sticky;
  top:0;
  height: 120px;
  background: blue;
  grid-area: header;
}

.nav {
  height: 100%;
  background: red;
  grid-area: nav;
}

.main {
  background: green;
  grid-area: main;

  
.item {
    height: 50px;
    padding: 20px;
 }

As you can see I have a simple layout with a header, a navigation menu and a main section. I want the header to remain on screen when scrolling down the results in the main section but when I exceed a certain height (potentially of the navigation menu?) the header disappears anyway.

Does any of you know a simple solution for this problem, that works with my layout?


Solution

  • Use min-height instead of height on the page element

    .page {
      min-height: 100vh;
        display: grid;
        grid-template-rows: auto 1fr;
        grid-template-columns: auto;
          grid-template-areas:
            "header header header"
            "nav main main";
    }
    
    .header {
      position:sticky;
      top:0;
      height: 120px;
      background: blue;
      grid-area: header;
    }
    
    .nav {
      background: red;
      grid-area: nav;
    }
    
    .main {
      background: green;
      grid-area: main;
    
      
    .item {
        height: 50px;
        padding: 20px;
     }
    <div class="page">
      <div class="header">
        kkk
      </div>
      
      <div class="nav">
        kkk
      </div>
      
      <div class="main">
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
        <div class="item">kkk</div>
      </div>
    </div>