1

I have a flex container in which there are a couple of divs. First one is just hanging out on the top and the bottom one, being a bit greedy, grows to fill the remaining height. This greedy div has 2 children side-by-side. This much works as expected.

I want the content inside the 2 siblings to be scrollable independently. If the content exceeds the flex-grown height, it should scroll. But I am unable to achieve this with the following code. When the content becomes too tall, a scroll bar is introduced on the entire page instead of just the child div. What should I change?

Unfortunately I am using a complex theme and everything else runs fine so I am not too inclined to change the styling of anything else like body or html tags.

body, html {
  margin: 0;
  padding: 0;
}
.navbar {
   height: 70px;
   width: 100%;
   background-color: red;
}
.all-except-navbar {
  height: calc(100vh - 70px);
  width: 100%;
  display: flex;
  flex-direction: column;
}
.chill-div {
  width: 100%;
  background-color: blue;
}
.greedy-div {
  width: 100%;
  background-color: green;
  flex: 1;
}
.the-parent {
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  background-color: pink;
}
.left-child {
  height: 100%;
  width: 35.5%;
  background-color: pink;
}
.right-child {
  height: 100%;
  width: 64%;
  background-color: grey;
}
.div-that-needs-to-scroll {
  background-color: yellow;
  width: 100%;
  height: 100%;
  overflow: auto;
  overflow-y:scroll;
}
<html>

  <body>

    <div class="navbar">
      Pretty navbar
    </div>

    <div class="all-except-navbar">

      <div class="chill-div">
        Top care-free div just chillin'
      </div>

      <div class="greedy-div">

        <div class="the-parent">

          <div class="left-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>


            </div>
          </div>
          <div class="right-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>

            </div>
          </div>


        </div>

      </div>

    </div>

  </body>

</html>

JS Fiddle

Uzair A.
  • 1,586
  • 2
  • 14
  • 30

3 Answers3

0

You need to fix the height with max-height property.

body, html {
  margin: 0;
  padding: 0;
}
.navbar {
   height: 70px;
   width: 100%;
   background-color: red;
}
.all-except-navbar {
  height: calc(100vh - 70px);
  width: 100%;
  display: flex;
  flex-direction: column;
}
.chill-div {
  width: 100%;
  background-color: blue;
}
.greedy-div {
  width: 100%;
  background-color: green;
  flex: 1;
}
.the-parent {
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  background-color: pink;
}
.left-child {
  max-height: 20rem;
  width: 35.5%;
  background-color: pink;
}
.right-child {
  max-height: 20rem;;
  width: 64%;
  background-color: grey;
}
.div-that-needs-to-scroll {
  background-color: yellow;
  width: 100%;
  height: 100%;
  overflow: auto;
  overflow-y:scroll;
}
<html>

  <body>

    <div class="navbar">
      Pretty navbar
    </div>

    <div class="all-except-navbar">

      <div class="chill-div">
        Top care-free div just chillin'
      </div>

      <div class="greedy-div">

        <div class="the-parent">

          <div class="left-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>


            </div>
          </div>
          <div class="right-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
               <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>

            </div>
          </div>


        </div>

      </div>

    </div>

  </body>

</html>
  • I cannot do that because I don't know what the max height is going to be. That's why I used flex grow. – Uzair A. Dec 30 '22 at 06:26
0

You should add overflow properties to greedy-div. then greedy-div grows to the all-except-navbar's height except chill-div (yellow background-color), but not to the height of overflowed contents (green background-color). So vertical scroll works properly.

body, html {
  margin: 0;
  padding: 0;
}
.navbar {
   height: 70px;
   width: 100%;
   background-color: red;
}
.all-except-navbar {
  height: calc(100vh - 70px);
  width: 100%;
  display: flex;
  flex-direction: column;
}
.chill-div {
  width: 100%;
  background-color: blue;
}
.greedy-div {
  width: 100%;
  background-color: green;
  flex: 1;
  overflow: auto;
  overflow-y: scroll;
}
.the-parent {
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  background-color: pink;
}
.left-child {
  height: 100%;
  width: 35.5%;
  background-color: pink;
}
.right-child {
  height: 100%;
  width: 64%;
  background-color: grey;
}
.div-that-needs-to-scroll {
  background-color: yellow;
  width: 100%;
  height: 100%;
}
<html>

  <body>

    <div class="navbar">
      Pretty navbar
    </div>

    <div class="all-except-navbar">

      <div class="chill-div">
        Top care-free div just chillin'
      </div>

      <div class="greedy-div">

        <div class="the-parent">

          <div class="left-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>


            </div>
          </div>
          <div class="right-child">
            <div class="div-that-needs-to-scroll">

              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>
              <div>
                Some content
              </div>

            </div>
          </div>


        </div>

      </div>

    </div>

  </body>

</html>
## Heading ##
seomoon
  • 1
  • 2
  • Thanks for the answer! But as I said in the question, I need the scrollbars to work independently. @Rahul Wakade's answer fixed that. – Uzair A. Dec 30 '22 at 06:29
0

I had faced the same issue and to resolve it I had to define the height or scroll behavior for the flex item present in column layout. In your case it is .greedy-div. What I observed is that the flex item's height was growing as per it's content as if height: auto is set to it. We expect it to never grow beyond it's flex container and the issue we see is strange behavior. I don't have any strong reasoning to support this observation but to resolve your issue you can either set

  1. .greedy-div {overflow: auto;}
  2. or .greedy-div {height: 0px;} // the 0px height here is to tell the flex layout that the div has some fixed height and it should not grow as it's content grow. It is not the final rendered height as flex rules will anyway override it but it tricks flex.
Rahul Wakade
  • 4,765
  • 2
  • 23
  • 25
  • Thanks a lot, this worked. I don't know why your answer was downvoted. If this is not the right approach then I hope the person who downvoted will provide an explanation in the comments. – Uzair A. Dec 30 '22 at 06:27
  • 1
    Don't know why but I expect some explanation for the same. Anyway I see some similar issues reported earlier https://stackoverflow.com/questions/43809612/prevent-a-child-element-from-overflowing-its-parent-in-flexbox, maybe content/use case is different but looks good read to me to add more knowledge around this issue. – Rahul Wakade Dec 30 '22 at 06:54