Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make absolute positioned div expand parent div height

You answered the question by yourself: "I know that absolute positioned elements are removed from the flow, thus ignored by other elements." So you can't set the parents height according to an absolutely positioned element.

You either use fixed heights or you need to involve JS.


Although stretching to elements with position: absolute is not possible, there are often solutions where you can avoid the absolute positioning while obtaining the same effect. Look at this fiddle that solves the problem in your particular case http://jsfiddle.net/gS9q7/

The trick is to reverse element order by floating both elements, the first to the right, the second to the left, so the second appears first.

.child1 {
    width: calc(100% - 160px);
    float: right;
}
.child2 {
    width: 145px;
    float: left;
}

Finally, add a clearfix to the parent and you're done (see the fiddle for the complete solution).

Generally, as long as the element with absolute position is positioned at the top of the parent element, chances are good that you find a workaround by floating the element.


There is a quite simple way to solve this.

You just have to duplicate the content of child1 and child2 in relative divs with display:none in parent div. Say child1_1 and child2_2. Put child2_2 on top and child1_1 at the bottom.

When your jquery (or whatever) calls the absolute div, just set the according relative div (child1_1 or child2_2) with display:block AND visibility:hidden. The relative child will still be invisible but will make parent's div higher.


Feeela is right but you can get a parent div contracting or expanding to a child element if you reverse your div positioning like this:

.parent {
    position: absolute;
    /* position it in the browser using the `left`, `top` and `margin` 
       attributes */
}

.child {
    position: relative;
    height: 100%;
    width: 100%;

    overflow: hidden;
    /* to pad or move it around using `left` and `top` inside the parent */
}

This should work for you.


This question was asked in 2012 before flexbox. The correct way to solve this problem using modern CSS is with a media query and a flex column reversal for mobile devices. No absolute positioning is needed.

https://jsfiddle.net/tnhsaesop/vjftq198/3/

HTML:

<div class="parent">
  <div style="background-color:lightgrey;">
    <p>
      I stay on top on desktop and I'm on bottom on mobile
    </p>
  </div>
  <div style="background-color:grey;">
    <p>
      I stay on bottom on desktop and I'm on top on mobile
    </p>
  </div>
</div>

CSS:

.parent {
  display: flex;
  flex-direction: column;
}

@media (max-width: 768px) {
  .parent {
    flex-direction: column-reverse;
  }
}

With pure JavaScript, you just need to retrieve the height of your static position child element .child1 using the getComputedStyle() method then set that retrieve value as the padding-top for that same child using the HTMLElement.style property.


Check and run the following Code Snippet for a practical example of what I described above:

/* JavaScript */

var child1 = document.querySelector(".child1");
var parent = document.getElementById("parent");

var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";
child1.style.paddingTop = childHeight;
/* CSS */

#parent { position: relative; width: 100%; }
.child1 { width: auto; }
.child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
<!-- HTML -->

<div id="parent">
    <div class="child1">STATIC</div>
    <div class="child2">ABSOLUTE</div>
</div>

There's a very simple hack that fixes this issue

Here's a codesandbox that illustrates the solution: https://codesandbox.io/s/00w06z1n5l

HTML

<div id="parent">
  <div class="hack">
   <div class="child">
   </div>
  </div>
</div>

CSS

.parent { position: relative; width: 100%; }
.hack { position: absolute; left:0; right:0; top:0;}
.child { position: absolute; left: 0; right: 0; bottom:0; }

you can play with the positioning of the hack div to affect where the child positions itself.

Here's a snippet:

html {
  font-family: sans-serif;
  text-align: center;
}

.container {
  border: 2px solid gray;
  height: 400px;
  display: flex;
  flex-direction: column;
}

.stuff-the-middle {
  background: papayawhip
    url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");
  flex: 1;
}

.parent {
  background: palevioletred;
  position: relative;
}

.hack {
  position: absolute;
  left: 0;
  top:0;
  right: 0;
}
.child {
  height: 40px;
  background: rgba(0, 0, 0, 0.5);
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
}
    <div class="container">
      <div class="stuff-the-middle">
        I have stuff annoyingly in th emiddle
      </div>
      <div class="parent">
        <div class="hack">
          <div class="child">
            I'm inside of my parent but absolutely on top
          </div>
        </div>
        I'm the parent
        <br /> You can modify my height
        <br /> and my child is always on top
        <br /> absolutely on top
        <br /> try removing this text
      </div>
    </div>