142

Is it possible to stack up multiple DIVs like:

<div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

So that all those inner DIVs have the same X and Y position? By default they all go below each other increasing the Y position by the height of the last previous DIV.

I have a feeling some sort of float or display or other trick could bite?

EDIT: The parent DIV has position relative, so, using position absolute does not seem to work.

Dom
  • 35,906
  • 12
  • 48
  • 80
Tower
  • 93,713
  • 124
  • 340
  • 500

9 Answers9

203

Position the outer div however you want, then position the inner divs using absolute. They'll all stack up.

.inner {
  position: absolute;
}
<div class="outer">
   <div class="inner">1</div>
   <div class="inner">2</div>
   <div class="inner">3</div>
   <div class="inner">4</div>
</div>
dota2pro
  • 6,421
  • 7
  • 34
  • 68
Matt
  • 2,492
  • 1
  • 14
  • 9
  • 1
    It doesn't seem to work. Maybe I should have mentioned that I have this scenario:
    stack this
    stack this
    stack this
    stack this
    – Tower Dec 15 '09 at 19:18
  • 2
    You want to absolutely position the divs that have "stack this" in them. It does work - I tried it before posting my original. If you don't put class selectors on your divs, adapt the div selection method in Eric's answer to select the stack divs. – Matt Dec 15 '09 at 19:26
  • 1
    Did not work for me either. Too many unkowns left to the viewers. – yan bellavance Oct 18 '16 at 15:49
  • I got the divs to stack be using position: relative and specifying height – yan bellavance Oct 18 '16 at 15:50
  • it might have something to do with display prop? – yan bellavance Oct 18 '16 at 15:51
  • The issue I'm finding with absolute is the parent container remains 0 x/y, and other content below appears on top of the absolute tabs. Maybe this is unrelated though and I should post another question about this... – Fiddle Freak Feb 10 '21 at 23:57
63

To add to Dave's answer:

div { position: relative; }
div div { position: absolute; top: 0; left: 0; }
Eric Wendelin
  • 41,234
  • 8
  • 61
  • 88
  • It doesn't seem to work. Maybe I should have mentioned that I have this scenario:
    stack this
    stack this
    stack this
    stack this
    – Tower Dec 15 '09 at 19:21
  • I *think* in that case you want to set "top: 0; left: 0;" on your div that has "position: relative". Definitely test IE6 on that, though as I can't say for certain that it'll work. – Eric Wendelin Dec 15 '09 at 19:25
27

You can now use CSS Grid to fix this.

<div class="outer">
  <div class="top"> </div>
  <div class="below"> </div>
</div>

And the css for this:

.outer {
  display: grid;
  grid-template: 1fr / 1fr;
  place-items: center;
}
.outer > * {
  grid-column: 1 / 1;
  grid-row: 1 / 1;
}
.outer .below {
  z-index: 2;
}
.outer .top {
  z-index: 1;
}
Moses Gitau
  • 717
  • 7
  • 7
  • 6
    Sounds complicated without an explanation – aderchox Sep 21 '20 at 07:25
  • This works very well, especially if, as in my case, you have multiple outer div blocks underneath each other with stacking divs inside. The above version without grid only work with one stacked group on a page – Kerry Mar 06 '22 at 11:34
12

If you mean by literally putting one on the top of the other, one on the top (Same X, Y positions, but different Z position), try using the z-index CSS attribute. This should work (untested)

<div>
    <div style='z-index: 1'>1</div>
    <div style='z-index: 2'>2</div>
    <div style='z-index: 3'>3</div>
    <div style='z-index: 4'>4</div>
</div>

This should show 4 on the top of 3, 3 on the top of 2, and so on. The higher the z-index is, the higher the element is positioned on the z-axis. I hope this helped you :)

Jimmie Lin
  • 2,179
  • 2
  • 22
  • 35
10

I'd prefer CSS grid for a better page layout (absolute divs can be overridden by other divs in the page.)

.container {
  width: 300px;
  height: 300px;
  margin: 0 auto;
  background-color: yellow;
  /* important part */
  display: grid;
  place-items: center;
  grid-template-areas: "inner-div";
}

.inner {
  height: 100px;
  width: 100px;
  /* important part */
  grid-area: inner-div;
}
<div class="container">
  <div class="inner" style="background-color: white;"></div>
  <div class="inner" style="background-color: red;"></div>
  <div class="inner" style="background-color: green;"></div>
  <div class="inner" style="background-color: blue;"></div>
  <div class="inner" style="background-color: purple;"></div>
</div>

If you hide the purple div with CSS, you'll see the blue div is at the top.

Here's a working link

Mario Petrovic
  • 5,868
  • 12
  • 32
  • 54
Ridvan Sumset
  • 412
  • 5
  • 11
  • 1
    this is the best answer coz `positon:absolute;` causes all margins and other such properties to collapse. – ashuvssut Dec 27 '20 at 19:56
7

style="position:absolute"

Dave Swersky
  • 34,150
  • 9
  • 76
  • 116
4

I positioned the divs slightly offset, so that you can see it at work.
HTML

<div class="outer">
  <div class="bot">BOT</div>
  <div class="top">TOP</div>
</div>

CSS

.outer {
  position: relative;
  margin-top: 20px;
}

.top {
  position: absolute;
  margin-top: -10px;
  background-color: green;
}

.bot {
  position: absolute;
  background-color: yellow;
}

https://codepen.io/anon/pen/EXxKzP

ryanjdillon
  • 15,701
  • 7
  • 81
  • 102
nycynik
  • 7,068
  • 6
  • 59
  • 82
  • That problem with doing this is that it turns your div's into span's. How do you keep them as block items? "display: block" does not change them back. – l008com Feb 12 '21 at 18:16
3

I had the same requirement which i have tried in below fiddle.

#container1 {
background-color:red;
position:absolute;
left:0;
top:0;
height:230px;
width:300px;
z-index:2;
}
#container2 {
background-color:blue;
position:absolute;
left:0;
top:0;
height:300px;
width:300px;
z-index:1;
}

#container {
position : relative;
height:350px;
width:350px;
background-color:yellow;
}

https://plnkr.co/edit/XnlneRFlvo1pB92UXCC6?p=preview

Raphael
  • 1,584
  • 1
  • 23
  • 41
0

I know that this post is a little old but I had the same problem and tried to fix it several hours. Finally I found the solution:

if we have 2 boxes positioned absolue

<div style='left: 100px; top: 100px; position: absolute; width: 200px; height: 200px;'></div>
<div style='left: 100px; top: 100px; position: absolute; width: 200px; height: 200px;'></div>

we do expect that there will be one box on the screen. To do that we must set margin-bottom equal to -height, so doing like this:

<div style='left: 100px; top: 100px; position: absolute; width: 200px; height: 200px; margin-bottom: -200px;'></div>
<div style='left: 100px; top: 100px; position: absolute; width: 200px; height: 200px; margin-bottom: -200px;'></div>

works fine for me.