1

Requirements are as follows:

Use either css or flex to do the following (which ever is most appropriate) and without the use of javascript:

A Parent div which has 2 columns and one row The content of child1 will determine the max-height of both columns However, it's possible the contents of child 2 could cause the height to exceed that of child1. In which case, child 2 should remain the same height but the contents of timeslots should scroll

This is what I have so far:

.parent {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
}

.child1 {
  background: #ddd;
  padding: 1rem;
}

.child2 {
  background: #eee;
  padding: 1rem;
  max-height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.timeslots {
  overflow-y: auto;
  flex: 1 1 auto;
}
<div class="parent">
  <div class="child1">
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
  </div>
  <div class="child2">
    <div class="timeslots">
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
    </div>
  </div>
</div>

I have tried the above and other variations using css grid, but in all cases, child 2 keeps stretching vertically, I can never get .timeslots to scroll.

I cannot provide fix heights, all content in both divs are dynamic and therefore so are the heights.

3 Answers 3

1

We can use a flex layout for the .parent, for the children, the first will be flex: 1fr same as defined in the grid.

The second will grow so flex: 1, we will absolute position the inner content, so we set the second column with position: relative, then finally, the inner content will be position: absolute and positioned with top, left, right and bottom as zero, using inset: 0.

.parent {
  display: flex;
  width:100%;
}

.child1 {
  background: #ddd;
  padding: 1rem;
  flex: 1fr;
}

.child2 {
position: relative;
  flex: 1;
  background: #eee;
  padding: 1rem;
  max-height: 100%;
  overflow-y: scroll;
  display: flex;
  flex-direction: column;
}

.timeslots {
  inset: 0;
  position: absolute;
  flex: 1 1 auto;
}
<div class="parent">
  <div class="child1">
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
  </div>
  <div class="child2">
    <div class="timeslots">
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

Main thing here is manipulating .timeslots to be scrollable and of height of .child1. Setting flex-direction: column; to .child2 is important so that we can manipulate height instead of width of .timeslots using flex properties.

Now, for the .timeslots. What we want is to make it not use it's own height but to fill available height (which will come from child1). We can do it by manipulating flex-basis and flex-grow properties. According to docs:

To completely ignore the size of the flex item during space distribution, set flex-basis to 0 and set a non-zero flex-grow value.

So, basically what we are saying here, I don't know how high (not wide beacuse of flex-direction: cou) item should be (flex-basis: 0;) but make it as high as possible (flex-grow: 1;) and if that height is bigger than the available height (.child's height) use scroll (overflow-y: auto;).

And at last we need to add overflow-y: auto; to make it scrollable and to actually see the effects of set flex properties.

.parent {
  display: flex;
}

.child1 {
  background: #ddd;
  padding: 1rem;
}

.child2 {
  background: #eee;
  padding: 1rem;
  display: flex;
  flex-direction: column;
}

.timeslots {
  flex-basis: 0;
  flex-grow: 1;
  overflow-y: auto;
}
<div class="parent">
  <div class="child1">
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
  </div>
  <div class="child2">
    <div class="timeslots">
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
    </div>
  </div>
</div>

Comments

1

If you want to stick to a grid layout, the trick is to give an height of 0 + a min-height of 100% to the container not allowed to grow taller than its siblling.

Snippet to demonstrate the idea:

div {
  box-sizing: border-box;
}

.parent {
  display: grid;
  grid-template-columns: auto 1fr;
}

.child1 {
  background: #ddd;
  padding: 1rem;
}

.child2 {
  background: #eee;
  padding: 1rem;
  height: 0;
  min-height: 100%;
  overflow:auto;
}
<div class="parent">
  <div class="child1">
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
  </div>
  <div class="child2">
    <div class="timeslots">
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Scroll if needed ...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
    </div>
  </div>
</div>
<hr>
opposite situation
<div class="parent">
  <div class="child1">
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
    Tall content here (sets height)<br>
  </div>
  <div class="child2">
    <div class="timeslots">
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Lots of scrollable content here...<br>
      Scroll if needed ...<br>
    </div>
  </div>
</div>

Note: display:flex;flex-direction:column; and display:grid are similar if it is about to draw a single column.

flex : draws a line by default

grid : draws a column by default

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.