Search code examples
htmlcsscss-grid

Scrollbar with grid inside grid using css grids


I have a html page that I don't want to scroll at the body scope, however, when using css grids that are nested, I can't control the body's scrollbar when content inside a nested grid overflows even when it has the property to scroll on overflow. The snippet I provide below I have a container which has grid and it contains a grid-area called workspace which has a component that is also a css grid. The component has content that forces the whole body to scroll, where I only want the content to scroll. I try messing with heights to 100% and 100vh, but no such luck.

body, html {
  margin: 0px;
}


.container {
  background-color: #282828;
    color: whitesmoke;
    display: grid;

    grid-template-columns: 1fr min-content;
    grid-template-rows: 42px 1fr;
    grid-template-areas: 
        'tabs sidebar'
        'workspace sidebar';
    height: 100vh;
}

.tabs {
    grid-area: tabs;
    background-color: violet; 
}

.sidebar {
    grid-area: sidebar;
    background-color: tomato;
    min-width: 50px;
}

.workspace {
    grid-area: workspace;
    background-color: blue;
}

.component {
  display: grid;
  grid-template-columns: 1fr;
    grid-template-rows: min-content 1fr;
    grid-template-areas: 
        'header'
      'content';
}

.header {
  grid-area: header;
}

.content {
  grid-area: content;
  overflow-y: scroll;
}
<div class="container">
  <div class="tabs">
  </div>
  <div class="sidebar">
  </div>
  <div class="workspace">
     <div class="component">
       <div class="header">
         <h1>My header</h1>
       </div>
       <div class="content">
          <h1>Temp</h1>
        <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>
    <h1>Temp</h1>

       </div>
       
       
    </div>
    
  </div>  
</div>


Solution

  • To have a scrollbar the container should have a height that if the content exceed then the scrollbar will be activated so whenever you want to have a scrollbar you have to keep in your mind that the border of your container should be defined some how.

    Now with that being said, if you don't want to have a fixed height then the main div should be a full screen then the nested container can have a scroll otherwise it will keep growing.

    the full screen because you don't want to provide any fixed height otherwise , if you have a fixed height then it will be more simple

    body, html {
      margin: 0px;
    }
    
    
    .container {
      background-color: #282828;
        color: whitesmoke;
        display: grid;
    
        grid-template-columns: 1fr min-content;
        grid-template-rows: 42px 1fr;
        grid-template-areas: 
            'tabs sidebar'
            'workspace sidebar';
        height: 100vh;
        position:absolute;
        left:0px;
        right:0px;
        top:0px;
        bottom:0px;
    }
    
    .tabs {
        grid-area: tabs;
        background-color: violet; 
    }
    
    .sidebar {
        grid-area: sidebar;
        background-color: tomato;
        min-width: 50px;
    }
    
    .workspace {
        grid-area: workspace;
        background-color: blue;
        position: relative;
         overflow-y: hidden;
    }
    
    .component {
      display: grid;
      grid-template-columns: 1fr;
        grid-template-rows: min-content 1fr;
        grid-template-areas: 
            'header'
          'content';
    }
    
    .header {
      grid-area: header;
    }
    
    .content {
      grid-area: content;
      overflow: auto;
        position: absolute;
        bottom: 0px;
        right: 0px;
        left: 0px;
        top: 80px;
    }
    <div class="container">
      <div class="tabs">
      </div>
      <div class="sidebar">
      </div>
      <div class="workspace">
         <div class="component">
           <div class="header">
             <h1>My header</h1>
           </div>
           <div class="content">
              <h1>Temp</h1>
            <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
        <h1>Temp</h1>
    
           </div>
           
           
        </div>
        
      </div>  
    </div>

    Upvote if you like it