1

Given the following HTML:

<!doctype html>
<html>
<body>

<span style="background-color: blue;">
   Some text here <br />
   Some text here <br />
   Some text here <br />
   Some text here <br />
</span>

<div style="position: relative; background-color: lightblue;" id="first">
   <div style="position: absolute; left: 180px; background-color: green;" id="second">
      This is an absolutely positioned div within a div relative to the page.
   </div>
</div>

<div style="background-color: red;" id="last">This is now positioned behind.</div>

</body>

</html>

(written for illustration purposes only).

Is there any way to make the flow of the document reset such that the div with id 'last' appears in flow with the rest of the document, after the absolutely positioned div (not behind). Without embedding it inside the divs with ids 'first' or 'second'.

I need to keep the general layout similar to this. But I don't want to have to use javascript to hackily position anything.

Any ideas or something I'm missing?

Rob
  • 1,687
  • 3
  • 22
  • 34

4 Answers4

3

One way would be to add a height rule to #first using css, making #first taller than #second and forcing #last out from underneath #second. That would be the easiest way I can think of. Does this help?

SamStar
  • 335
  • 2
  • 17
  • That works ... if you know the height of #first. If the height varies due to variable amounts of content, or wrapping when the browser is resized, then it's not good enough. This should be a simple layout,but it's far from it. It would really help to have a way to do this without a fixed height. – Anthony Feb 11 '12 at 14:30
  • Well, the height would be flexible, you would just have to adjust it page by page, which could be a pain. Outside of that your best bet would probably be to absolutely position #last as well. However at this point though, it would be best to remember, if you have to work extra hard to get everything back into a *flexible* document flow after the absolutely positioned #second, the you might do better to look for an alternative to positioning #second absolutely. If flexibility does not matter... go have a bash! – SamStar Feb 14 '12 at 22:53
  • Page by page? What if #second contains user-entered or dynamically served content? What if it wraps when the user resizes the browser window and the width changes? No fixed height will work for that - html documents are meant to deal with flow. Also, surely absolutely positioning #last would put it at a fixed position, which is not what is wanted. I agree that as far as I can see, absolute positioning doesn't handle this scenario well enough. – Anthony Feb 15 '12 at 21:04
  • hmm... I see what you are saying. Still in most of your scenarios, absolute positioning really doesn't seem like a good choice of position... might be missing something... but the whole point of absolute positioning is to achieve a fixed element. So it (absolute positioning) would be inherently hampering to document *flow*. – SamStar Feb 16 '12 at 02:46
1

First-- why does #second need to be absolutely positioned?

To maintain document flow you should have a height property on both #first and #second, and make sure the height on #first is greater than or equal to the height of #second

HandiworkNYC.com
  • 10,914
  • 25
  • 92
  • 154
  • psoition: absolute within position: relative is a well-known css hack to achieve some layouts, like columns inside a div. The problem is, it makes it hard to lay something out below it without it having a fixed height. Css hacks generally aren't rigorous solutions. – Anthony Feb 11 '12 at 14:43
0

In answer to the question of positioning something following a div whose contents are variable (and hence a variable height), I used the following code to position my controls div following a variable-height middle div. I wouldn't consider it a 'hack', since the browser doesn't know at load time how high the middle div is.

    $('#middleDiv')
    .load(dynamicContent, function () {
        $('#controls')
        .css('top', $('article').height() - ($('#controls').height()) / 2);
    });

The $('#middleDiv').load(xxx) dynamically loads in the HTML snippet I want to display on the page. Since load is asynchronous I have a completion anonymous function to calculate the top of the controls div. Within the dynamic HTML I have a single article element which I can use to calculate the height of the dynamic content - $('article').height.

The second part of the calculation subtracts half the height of the controls to position it just below my content.

The CSS must use relative positioning for this to work:

#controls {
    position:relative;
    left:376px;
    width:100px;
}

#nextExercise {
    height:45px;
    margin-bottom:20px;
    width:100%;
}

The controls on this page are simple, just a button. I added a bottom margin to leave a bit of whitespace following the controls.

I happened to use an absolute position for the article element itself, although I am sure it would also work with a position:relative element.

article {
    position:absolute;
    top:65px;
    left:145px;
    width:480px;
}
wolfstevent
  • 703
  • 8
  • 13
0

The #last element isn't actually behind #first. It's below it, but #first has 0 height because its only child is pulled out of the document flow by absolute positioning.

Would a different approach serve your needs?

  • #second could have a left margin of 180px, then use display: inline-block to make it fit its contents.
  • #second could be position: relative instead of absolute, then use display: inline-block to make it fit its contents.

Here are a couple of examples: http://codepen.io/Ghodmode/pen/diqcD

You didn't exactly explain what you need to do, or why #second needs to be absolutely positioned. We might be able to provide a better solution with a little more information.

Vince
  • 3,962
  • 3
  • 33
  • 58