163

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
  • 38,906
  • 12
  • 52
  • 81
Tower
  • 98,741
  • 129
  • 357
  • 507

11 Answers11

225

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
  • 7,220
  • 7
  • 44
  • 79
Matt
  • 2,720
  • 1
  • 15
  • 9
  • 2
    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
  • 1
    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
  • Dont forget to set parent element style to { display: 'grid' } – spacedev Mar 27 '23 at 08:59
66

To add to Dave's answer:

div { position: relative; }
div div { position: absolute; top: 0; left: 0; }
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
Eric Wendelin
  • 43,147
  • 9
  • 68
  • 92
  • 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
42

You can now use CSS Grid to fix this.

<div class="outer">
  <div class="top"> top </div>
  <div class="below"> 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: 1;
  background-color: aqua;
}
.outer .top {
  z-index: 2;
  background-color: brown;
}

The lower the z-index, the lower the level. The level with the highest z-index is in the foreground.

Alex44
  • 3,597
  • 7
  • 39
  • 56
Moses Gitau
  • 947
  • 8
  • 7
17

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
  • 7,500
  • 14
  • 42
  • 62
Ridvan Sumset
  • 508
  • 6
  • 13
  • 5
    this is the best answer coz `positon:absolute;` causes all margins and other such properties to collapse. – ashuvssut Dec 27 '20 at 19:56
  • https://www.stefanjudis.com/today-i-learned/css-grid-can-be-used-to-stack-elements/ – droid192 Nov 26 '22 at 18:43
  • 1
    Addind to @ashuvssut's comment, `position: absolute` also often requires hard-coding the container's width and height, because the children no longer contribute to its size and otherwise cause the container to collapse to 0×0 (which might be undesirable). – balu Jun 01 '23 at 18:02
9

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,205
  • 2
  • 23
  • 35
6

style="position:absolute"

Dave Swersky
  • 34,502
  • 9
  • 78
  • 118
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
  • 17,658
  • 9
  • 85
  • 110
nycynik
  • 7,371
  • 8
  • 62
  • 87
  • 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,738
  • 2
  • 27
  • 47
2

The answer that provides position:absolute is now outdated.

In currently supported browsers, it is much easier to achieve the same using CSS grid. This will ensure that the elements are still part of the page layout (issue produced with position:absolute.

This is a blog post explaining how to achieve this: https://zelig880.com/how-to-stack-two-elements-on-top-of-each-other-without-using-position-absolute

And this is a codepen with a live example:https://codepen.io/zelig880/pen/oNdZWNa

Quick code:

.container_row{
  display: grid;
}

.layer1, .layer2{
  grid-column: 1;
  grid-row: 1;
}

.layer1{
  color: blue;
  background: red;
  animation-direction: reverse;
}

.layer2{
  color: white;
  background: blue;
}
.layer1, .layer2 {
  animation-name: fade;
  animation-duration: 10s;
}

@keyframes fade {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<div class="container_row">
    <div class="layer1">
        I am the layer behind
    </div>
    <div class="layer2">
        I am actually on top
    </div>
</div>
<div class="container_row">
   Yuppi! This line is positioned successfully! This would not have been the case with position:absolute
</div>
Zelig880
  • 500
  • 4
  • 6
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.

0

If you have issues related to affecting other elements' positions you can do it like this.

<div class="container">
  <div>Div 1</div>
  <div>Div 2 on top of div 1</div>
  <div>Div 3 on top of div 1 and 2</div>
</div>

<style type="text/css">
  .container {
    /* to align absolute children to relative parent */
    position: relative;
  }
  .container > div {
    /* no need for z-index, the lower div will be higher 
       use z-index if you want a specific div to be on top of others */
    position: absolute;
  }
</style>

David Antoon
lizardkingLK
  • 25
  • 2
  • 8