[html] Make absolute positioned div expand parent div height

As you can see in the CSS below, I want child2 to position itself before child1. This is because the site I'm currently developing should also work on mobile devices, on which the child2 should be at the bottom, as it contains the navigation which I want below the content on the mobile devices. - Why not 2 masterpages? This is the only 2 divs which are repositioned in the entire HTML, so 2 masterpages for this minor change is an overkill.

HTML:

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

CSS:

parent { position: relative; width: 100%; }
child1 { width: auto; margin-left: 160px; }
child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }

child2 has dynamic height, as different subsites could have more or less navigation items.

I know that absolute positioned elements are removed from the flow, thus ignored by other elements.
I tried setting overflow:hidden; on the parent div, but that didn't help, neither does the clearfix.

My last resort will be JavaScript to reposition the two divs accordingly, but for now I'll try and see if there exist a non-JavaScript way of doing this.

This question is related to html css position master-pages parent-child

The answer is


I came up with another solution, which I don't love but gets the job done.

Basically duplicate the child elements in such a way that the duplicates are not visible.

<div id="parent">
    <div class="width-calc">
        <div class="child1"></div>
        <div class="child2"></div>
    </div>

    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

.width-calc {
    height: 0;
    overflow: hidden;
}

If those child elements contain little markup, then the impact will be small.


Also consider next approach:

CSS:

.parent {
  height: 100%;
}
.parent:after {
  content: '';
  display: block;
}

Also since you are trying to reposition divs consider css grid


Try this, it was worked for me

.child {
    width: 100%;
    position: absolute;
    top: 0px;
    bottom: 0px;
    z-index: 1;
}

It will set child height to parent height


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;
  }
}

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:

_x000D_
_x000D_
html {_x000D_
  font-family: sans-serif;_x000D_
  text-align: center;_x000D_
}_x000D_
_x000D_
.container {_x000D_
  border: 2px solid gray;_x000D_
  height: 400px;_x000D_
  display: flex;_x000D_
  flex-direction: column;_x000D_
}_x000D_
_x000D_
.stuff-the-middle {_x000D_
  background: papayawhip_x000D_
    url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");_x000D_
  flex: 1;_x000D_
}_x000D_
_x000D_
.parent {_x000D_
  background: palevioletred;_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
.hack {_x000D_
  position: absolute;_x000D_
  left: 0;_x000D_
  top:0;_x000D_
  right: 0;_x000D_
}_x000D_
.child {_x000D_
  height: 40px;_x000D_
  background: rgba(0, 0, 0, 0.5);_x000D_
  position: absolute;_x000D_
  bottom: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
}
_x000D_
    <div class="container">_x000D_
      <div class="stuff-the-middle">_x000D_
        I have stuff annoyingly in th emiddle_x000D_
      </div>_x000D_
      <div class="parent">_x000D_
        <div class="hack">_x000D_
          <div class="child">_x000D_
            I'm inside of my parent but absolutely on top_x000D_
          </div>_x000D_
        </div>_x000D_
        I'm the parent_x000D_
        <br /> You can modify my height_x000D_
        <br /> and my child is always on top_x000D_
        <br /> absolutely on top_x000D_
        <br /> try removing this text_x000D_
      </div>_x000D_
    </div>
_x000D_
_x000D_
_x000D_


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.


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

Here is the JS example:

---------- jQuery JS example--------------------

    function findEnvelopSizeOfAbsolutelyPositionedChildren(containerSelector){
        var maxX = $(containerSelector).width(), maxY = $(containerSelector).height();

        $(containerSelector).children().each(function (i){
            if (maxX < parseInt($(this).css('left')) + $(this).width()){
                maxX = parseInt($(this).css('left')) + $(this).width();
            }
            if (maxY < parseInt($(this).css('top')) + $(this).height()){
                maxY = parseInt($(this).css('top')) + $(this).height();
            }
        });
        return {
            'width': maxX,
            'height': maxY
        }
    }

    var specBodySize = findEnvelopSizeOfAbsolutelyPositionedSubDivs("#SpecBody");
    $("#SpecBody").width(specBodySize.width);
    $("#SpecBody").height(specBodySize.height);

This is very similar to what @ChrisC suggested. It is not using an absolute positioned element, but a relative one. Maybe could work for you

<div class="container">
  <div class="my-child"></div>
</div>

And your css like this:

.container{
    background-color: red;
    position: relative;
    border: 1px solid black;
    width: 100%;
}

.my-child{
    position: relative;
    top: 0;
    left: 100%;
    height: 100px;
    width: 100px;
    margin-left: -100px;
    background-color: blue;
}

https://jsfiddle.net/royriojas/dndjwa6t/


I had a similar problem. To solve this (instead of calculate the iframe's height using the body, document or window) I created a div that wraps the whole page content (a div with an id="page" for example) and then I used its height.


There is a better way to do this now. You can use the bottom property.

    .my-element {
      position: absolute;
      bottom: 30px;
    }

Absolute views position themselves against the nearest ancestor that isn't statically positioned (position: static), therefore if you want an absolute view positioned against a given parent, set the parent position to relative and the child to position to absolute


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.


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:

_x000D_
_x000D_
/* JavaScript */_x000D_
_x000D_
var child1 = document.querySelector(".child1");_x000D_
var parent = document.getElementById("parent");_x000D_
_x000D_
var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";_x000D_
child1.style.paddingTop = childHeight;
_x000D_
/* CSS */_x000D_
_x000D_
#parent { position: relative; width: 100%; }_x000D_
.child1 { width: auto; }_x000D_
.child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }_x000D_
html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
_x000D_
<!-- HTML -->_x000D_
_x000D_
<div id="parent">_x000D_
    <div class="child1">STATIC</div>_x000D_
    <div class="child2">ABSOLUTE</div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


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.


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to position

How does the "position: sticky;" property work? React Native absolute positioning horizontal centre RecyclerView - Get view at particular position RecyclerView - How to smooth scroll to top of item on a certain position? How to find index of STRING array in Java from a given value? Insert node at a certain position in a linked list C++ How to position the Button exactly in CSS Float a DIV on top of another DIV Iframe positioning css - position div to bottom of containing div

Examples related to master-pages

how to access master page control from content page Make absolute positioned div expand parent div height MVC 3: How to render a view without its layout page when loaded via ajax? a page can have only one server-side form tag Parser Error: '_Default' is not allowed here because it does not extend class 'System.Web.UI.Page' & MasterType declaration how to display none through code behind Where does error CS0433 "Type 'X' already exists in both A.dll and B.dll " come from? How to include Javascript file in Asp.Net page Master Page Weirdness - "Content controls have to be top-level controls in a content page or a nested master page that references a master page." Can I dynamically add HTML within a div tag from C# on load event?

Examples related to parent-child

The specified child already has a parent. You must call removeView() on the child's parent first (Android) Example of waitpid() in use? get parent's view from a layout CSS :: child set to change color on parent hover, but changes also when hovered itself How to pass data from 2nd activity to 1st activity when pressed back? - android Make absolute positioned div expand parent div height JavaScript DOM: Find Element Index In Container How to set opacity in parent div and not affect in child div? How to select <td> of the <table> with javascript? Maven: Non-resolvable parent POM