Gabriel
Gabriel

Reputation: 2190

Expanding element vertically to fill parent's remaining space

Given this markup and styles:

<div class="a">
  <div class="b">Fixed height</div>
  <div class="b">Fixed height</div>
  <div class="expand">Expand</div>
  <div>Fixed height</div>
</div>

.a {
  float: left; width: 100%; height: 500px;
}
.a>div {
  float: left; width: 100%;
}
.b {
  width: 50%;
}

I want to expand .expand to fill the empty space in the parent. See attached image.

Current attempt is to compute the current height of the parent, remove its height property and set the height of .expand to the difference of these two values. If there are more than one .expand siblings, the height is divided by the amount of them.

If the .expand is also a column (.b in this example), they get the 100% of their parent's height.

$(".expand").css({height:"auto"}).each(function() {
        var parent=$(this).parent();

        if($(this).is(".b")) {
            $(this).css("height",$(parent).innerHeight());
        } else {
            var siblings=$(parent).children(".expand");
            var siblingsTotalH=0;
            $(siblings).each(function() { siblingsTotalH+=$(this).outerHeight(); });            

            var currentH=$(parent).innerHeight();
            var currentCssH=$(parent).css("height"); //Save the value to restore it later
            $(parent).css("height","auto");

            var minH=$(parent).innerHeight()-siblingsTotalH;            
            var dif=(currentH-minH)/siblings.length;

            if(dif>0) $(this).css("height",dif);

            $(parent).css("height",currentCssH);            
        }
    });

That way it works but the working cases are limited. .expands cannot be inline elements and case B requires a different markup:

<div class="a">
      <div class="b">Fixed height</div>
      <div class="b">Fixed height</div>
      <div class="expand">
           <div class="b expand">Expand</div>
           <div class="b expand">Expand</div>
      </div>
      <div>Fixed height</div>
    </div>

I leave this question in order to see if there is a more suitable solution.

Are there any simple solution to acheive this? Or are there a jQuery plugin that does this? I couldn't find any for this particular cases.

Altough there are similar questions here, in this case I cannot change the markup or use display: table or CSS flex because it will mess with other elements. I'm looking for a JavaScript solution.

The styles are simplified to show an easy to read example. Image to clarify including other similar cases (left, initial state, right expected results).

These are examples. The point is to expand regardless of what other elements there are or how are they arranged.

enter image description here

Upvotes: 2

Views: 116

Answers (1)

Steven Kaspar
Steven Kaspar

Reputation: 1187

You can use offsetHeights to do calculations. This fiddle shows how to do a header footer and middle container

https://jsfiddle.net/stevenkaspar/hk1escoj/

<div id='header'>
  header
  <p>
    another line
  </p>
</div>
<div id='container'>
  container
</div>

<div id='footer'>
  container
</div>
var resize = function(){
  var windwow_height = window.innerHeight;
  var footer_height = document.getElementById('footer').offsetHeight;
  var header_height = document.getElementById('header').offsetHeight;
  var container_height = windwow_height - (header_height + footer_height);

  document.getElementById('container').style.height = container_height + 'px';
}

window.onresize = resize;
resize();

Upvotes: 1

Related Questions