views:

28161

answers:

11

Given a template where the HTML cannot be modified because of other requirements, how is it possible to display a div above another div when they are not in that order in the HTML and both divs contain data that could produce a varying height and width.

HTML:

<div id="wrapper">
    <div id="firstDiv">
        Content to be below in this situation
    </div>
    <div id="secondDiv">
        Content to be above in this situation
    </div>
</div>
Other elements

Hopefully it is obvious that the desired result is:

Content to be above in this situation
Content to be below in this situation
Other elements

When the dimensions are fixed it easy to position them where needed, but I need some ideas for when the content is variable. For the sake of this scenario, please just consider the width to be 100% on both.

Edit: A CSS solution is the most ideal solution. Thank you for the Javascript options mentioned. Without getting too wordy about what or why (or who) ... I am specifically looking for a CSS only solution (and it will probably have to be met with other solutions if that doesn't pan out).

One more ... there are other elements following this. A good suggestion was mentioned given the limited scenario I demonstrated -- given that it might be the best answer, but I am looking to also make sure elements following this aren't impacted.

A: 

I don't think that's possible (at least with CSS2) However you should be able to achieve the desired results using JavaScript

Muxa
A: 

Well, with a bit of absolute positioning and some dodgy margin setting, I can get close, but it's not perfect or pretty:

#wrapper { position: relative; margin-top: 4em; }
#firstDiv { position: absolute; top: 0; width: 100%; }
#secondDiv { position: absolute; bottom: 0; width: 100%; }

The "margin-top: 4em" is the particularly nasty bit: this margin needs to be adjusted according to the amount of content in the firstDiv. Depending on your exact requirements, this might be possible, but I'm hoping anyway that someone might be able to build on this for a solid solution.

Eric's comment about javascript should probably be pursued.

Bobby Jack
That's more or less what I came up with before I gave up.
Paolo Bergantino
+2  A: 

If you know, or can enforce the size for the to-be-upper element, you could use

position : absolute;

In your css and give the divs their position.

otherwise javascript seems the only way to go:

fd = document.getElementById( 'firstDiv' );
sd = document.getElementById( 'secondDiv' );
fd.parentNode.removeChild( fd );
sd.parentNode.insertAfter( fd, sd );

or something similar.

edit: I just found this which might be useful: w3 document css3 move-to

Kris
Thanks, I will consider something like this if no CSS is available
devmode
+7  A: 

As others have said, this isn't something you'd want to be doing in CSS. You can fudge it with absolute positioning and strange margins, but it's just not a robust solution. The best option in your case would be to turn to javascript. In jQuery, this is a very simple task:

$('#secondDiv').insertBefore('#firstDiv');

or more generically:

$('.swapMe').each(function(i, el) {
    $(el).insertBefore($(el).prev());
});
nickf
Thanks, we use jQuery .. I will consider this
devmode
+3  A: 

Here's a solution:

<style>
#firstDiv {
    position:absolute; top:100%;
}
#wrapper {
    position:relative; 
}

But I suspect you have some content that follows the wrapper div...

buti-oxa
Yes ... trying not to be too wordy with the situation, but there are other elements following. Good suggestion though given the limited HTML provided -- might work for someone else.
devmode
+2  A: 

Negative top margins can achieve this effect, but they would need to be customized for each page. For instance, this markup...

<div class="product">
<h2>Greatest Product Ever</h2>
<p class="desc">This paragraph appears in the source code directly after the heading and will appear in the search results.</p>
<p class="sidenote">Note: This information appears in HTML after the product description appearing below.</p>
</div>

...and this CSS...

.product { width: 400px; }
.desc { margin-top: 5em; }
.sidenote { margin-top: -7em; }

...would allow you to pull the second paragraph above the first.

Of course, you'll have to manually tweak your CSS for different description lengths so that the intro paragraph jumps up the appropriate amount, but if you have limited control over the other parts and full control over markup and CSS then this might be an option.

Carl Camera
+1 I tried that and works like a charm, thanks man.
Chepech
A: 

hey how can I make one div on top of another example one will look like being on the background and the second one will be covering part of the first one

A: 

CSS really shouldn't be used to restructure the HTML backend. However, it is possible if you know the height of both elements involved and are feeling hackish. Also, text selection will be messed up when going between the divs, but that's because the HTML and CSS order are opposite.

#firstDiv { position: relative; top: YYYpx; height: XXXpx; }
#secondDiv { position: relative; top: -XXXpx; height: YYYpx; }

Where XXX and YYY are the heights of firstDiv and secondDiv respectively. This will work with trailing elements, unlike the top answer.

+2  A: 

There is absolutely no way to achieve what you want through CSS alone -- unless:

  1. You know the exact rendered height of each element (if so, you can absolutely position the content). If you're dealing with dynamically generated content, you're out of luck.
  2. You know the exact number of these elements there will be. Again, if you need to do this for several chunks of content that are generated dynamically, you're out of luck.

If the above are true then you can do what you want by absolutely positioning the elements --

#wrapper { position: relative; }
#firstDiv { position: absolute; height: 100px; top: 110px; }
#secondDiv { position: absolute; height: 100px; top: 0; }

Again, if you don't know the height want for at least #firstDiv, there's no way you can do what you want via CSS alone. If any of this content is dynamic, you will have to use javascript.

bigmattyh
A: 

For CSS Only solution 1. Either height of wrapper should be fixed or 2. height of second div should be fixed

KoolKabin
A: 

http://www.w3schools.com/Css/pr_pos_z-index.asp

You might have to alter the other elements a little afterwards, but as far as I know, this is the most valid option while using CSS only.