2
votes

I have two divs stacked on top of each other. The top div contains an accordion menu, and is 300px tall when fully expanded. The CSS for the bottom div is:

height:calc(100vh - 300px)

This works great when the accordion in the top div is fully expanded - the bottom div fills up the rest of the vertical space of the viewport.

The problem occurs when the accordion in the top div gets collapsed. Now the top div is only 50px tall, but the CSS for the bottom div is still subtracting 300px from 100vh.

Is it possible to have the value being subtracted from 100vh be a variable instead of a fixed value? So instead of a hard coded pixel amount, it's subtracting whatever the height of the top div is.

2
No, that is not possible. But the accordion presumably doesn't magically collapse all by itself, but there is some JavaScript involved. So when the script makes the accordion collapse, you can also make it set a class on the bottom div, that applies a different height value. - CBroe
Yeah, I was thinking there would need to be some js involved but didn't want to overlook a CSS solution. Thanks for your reply. - John Beckwith

2 Answers

0
votes

You can use a sibling selector to hardcode a new value if your markup is structured a certain way.

In the code below a sibling selector for the expanded accordion is used to target and override the default calculated height of the div below it with a new one

I've tried to explain it using this fiddle: https://jsfiddle.net/L4ae0rq6/

HTML

<div class="accordion collapsed"></div>
<div class="calc"></div>
<hr/>
<div class="accordion expanded"></div>
<div class="calc"></div>

CSS

.accordion.collapsed {
    height: 50px;
    width: 200px;
    background: grey;
}

.accordion.expanded {
    height: 100px;
    width: 200px;
    background: grey;
}

.accordion.expanded + .calc {
    height: calc(100vh - 300px);
}

.calc {
    width: 200px;
    height: calc(100vh - 200px);
    background: lightgrey;
}

Hope this helps.

0
votes

You can use flex.

Check the following:

.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.expandable {
  background: red;
  min-height: 40px;
}
.expandable.expanded {
  flex-basis: 300px;
}
.filler {
  background: green;
  flex-grow: 1;
}

So when the .expanded class is added it takes a space of 300 pixels otherwise a minimum of 40 pixels.

In any case the .filler will take the remaing space as long as you use flex-grow: 1.

Demo