skip to Main Content

I know this is a common question, but I haven’t seen anyone answer it without switching away from grid or hardcoding pixel sizes (which seems like bad practice), so wanted to see if it’s possible:

I am trying to create a simple grid with two cells. I want the top cell to dynamically size to what’s left of the parent grid container. I want the bottom cell to remain fixed at the bottom of the parent grid container.

The top container will contain all the messages to read in a chat app.
The bottom container will contain a compose bar to write and send a message.

To feel natural, the top container (message list) should scroll when it overflows.
The bottom container (compose bar) should remain fixed at the bottom of the screen.

The problem with my code is that the top container always expands to the full length of the stacked messages when the list is long enough to overflow the container. (I am mapping an array of messages to divs within chat-message-list). It’s so aggressive, it not only pushed the bottom cell below the fold, it pushed elements outside the grid down as well.

#chat {
  display: grid;
  grid-template: 1fr 64px / 100%;
  height: 100%;
  /* This does nothing */
}

#chat-read {
  grid-area: 1 / 1 / span 1 / span 1;
  overflow: scroll;
  margin-bottom: 0px;
}

#chat-compose {
  grid-area: 2 / 1 / span 1 / span 1;
}

#chat-message-list {
  display: flex;
}
<div id="chat">
  <div id="chat-read">
    <div id="chat-message-list">
      ... /* Variable amount of divs containing a chat message each */
    </div>
  </div>
  <div id="chat-compose">
    ... /* Fixed-height compose bar */
  </div>
</div>

Thanks in advance!

2

Answers


  1. Use below code:

    *{margin: 0;padding: 0;box-sizing: border-box;}
    p{margin-bottom: 10px;}
    #chat {
      display: grid;
      grid-template: 1fr 100px / 100%;
      height: 100%; /* This does nothing */
    }
    
    #chat-read {
      grid-area: 1 / 1 / span 1 / span 1;
      overflow-y: scroll;
      margin-bottom: 0px;
      padding: 20px;
      background-color: azure;
    }
    
    #chat-compose {
      grid-area: 2 / 1 / span 1 / span 1;
      overflow-y: scroll;
      background-color: antiquewhite;
      padding: 20px;
    }
    
    #chat-message-list {
      display: flex;
      flex-direction: column;
    }
    <div id="chat">
            <div id="chat-read">
              <div id="chat-message-list">
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
              </div>
            </div>
            <div id="chat-compose">
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
                <p>Hi</p>
                <p>Hello,</p>
            </div>
          </div>
    Login or Signup to reply.
  2. You need to specify a maximum height for, ideally, the body or the parent of your chat div for the 100% height to take effect.

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
     ::before,
     ::after {
      box-sizing: inherit;
    }
    
    html,
    body {
      height: 100%;
    }
    
    body {
      max-height: 100vh;
    }
    
    #chat {
      display: grid;
      grid-template: 1fr 64px / 100%;
      height: 100%;
    }
    
    #chat-read {
      grid-area: 1 / 1 / span 1 / span 1;
      overflow: auto;
      margin-bottom: 0px;
    }
    
    #chat-compose {
      grid-area: 2 / 1 / span 1 / span 1;
      background: lightblue;
    }
    
    #chat-message-list {
      display: flex;
      flex-direction: column;
    }
    <div id="chat">
      <div id="chat-read">
        <div id="chat-message-list">
          <div>Chat 1</div>
          <div>Chat 2</div>
          <div>Chat 3</div>
          <div>Chat 4</div>
          <div>Chat 5</div>
          <div>Chat 6</div>
          <div>Chat 7</div>
          <div>Chat 8</div>
          <div>Chat 9</div>
          <div>Chat 10</div>
          <div>Chat 11</div>
          <div>Chat 12</div>
          <div>Chat 13</div>
          <div>Chat 14</div>
          <div>Chat 15</div>
          <div>Chat 16</div>
          <div>Chat 17</div>
          <div>Chat 18</div>
          <div>Chat 19</div>
          <div>Chat 20</div>
          <div>Chat 21</div>
          <div>Chat 22</div>
          <div>Chat 23</div>
          <div>Chat 24</div>
          <div>Chat 25</div>
          <div>Chat 26</div>
          <div>Chat 27</div>
          <div>Chat 28</div>
          <div>Chat 29</div>
          <div>Chat 30</div>
        </div>
      </div>
      <div id="chat-compose">
        ... /* Fixed-height compose bar */
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search