Home > Back-end >  How do I auto-add a vertical scrollbar to a vertical flex: 1 element inside another vertical flex: 1
How do I auto-add a vertical scrollbar to a vertical flex: 1 element inside another vertical flex: 1

Time:11-05

I'm trying to achieve a chat-service-like layout with HTML/CSS where the entire page takes up 100% the height of the screen, the header and footer are dynamic based on their nested markup and the content area takes up the remaining height of the screen.

In addition, within the dynamic-height content area, I want to have a vertical flex layout where one part of the content area is dynamic based on the nested markup, and the second area takes up the remaining height, and if the content in that second area causes the entire layout to exceed the total height of the screen, I want to add a vertical scrollbar to that second area to handle the overflow.

Put simply, I want to create a chat screen where the existing messages area takes up a majority of the screen and when the message content is too long, instead of the screen scrolling, the messages area only gets a vertical scrollbar. Hopefully that makes sense.

Below is the basic markup I've been playing with. With this markup, I'm trying to get the pink area to get a vertical scrollbar when the content is too long for the total height of the screen. Unfortunately, after heavily searching related topics on SO, I can't seem to figure out what the right combination of HTML/CSS to achieve what I'm looking for. Any advice would be greatly appreciated. Thank you.

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

body {
  height: 100%;
}

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.header {
  background: yellow;
}

.content {
  flex: 1;
  padding: 20px;
}

.content-container {
  background: #DDD;
  display: flex;
  flex-direction: column;
  margin: auto;
  width: 500px;
}

.messages {
  background: #FFC8FF;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.new-message-input {
  border: black solid 1px;
  height: 150px;
  margin-top: 20px;
}

.footer {
  background: yellow;
}
<div >
  <div >
    <h1>Header</h1>
  </div>
  <div >
    <div >
      <div >
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
      </div>
      <div >
      </div>
    </div>
  </div>
  <div >
    <p>Footer</p>
  </div>
</div>

CodePudding user response:

You are almost good. You need an extra min-height:0 and a height: 100%

.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.header {
  background: yellow;
}

.content {
  flex: 1;
  padding: 20px;
  min-height: 0; /* ADDED */
}

.content-container {
  background: #DDD;
  display: flex;
  flex-direction: column;
  margin: auto;
  width: 500px;
  height: 100%; /* ADDED */
}

.messages {
  background: #FFC8FF;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.new-message-input {
  border: black solid 1px;
  height: 150px;
  margin-top: 20px;
}

.footer {
  background: yellow;
}


* {
  box-sizing: border-box;
}
body {
  margin: 0;
}
<div >
  <div >
    <h1>Header</h1>
  </div>
  <div >
    <div >
      <div >
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
        <p>A message...</p>
      </div>
      <div >
      </div>
    </div>
  </div>
  <div >
    <p>Footer</p>
  </div>
</div>

  • Related