[css] CSS: How to position two elements on top of each other, without specifying a height?

I have two DIVs that I need to position exactly on top of each other. However, when I do that, the formatting gets all screwed up because the containing DIV acts like there is no height. I think this is the expected behavior with position:absolute but I need to find a way to position these two elements on top of each other and have the container stretch as the content stretches:

The top left edge of .layer2 should be exactly aligned to the top left edge of layer1

<!-- HTML -->
<div class="container_row">
    <div class="layer1">
        Lorem ipsum...
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>

/* CSS */
.container_row {}

.layer1 {
    position:absolute;
    z-index: 1;
}

.layer2 {
    position:absolute;
    z-index: 2;
}

This question is related to css

The answer is


Due to absolute positioning removing the elements from the document flow position: absolute is not the right tool for the job. Depending on the exact layout you want to create you will be successful using negative margins, position:relative or maybe even transform: translate. Show us a sample of what you want to do we can help you better.


Great answer, "mu is too short". I was seeking the exact same thing, and after reading your post I found a solution that fitted my problem.

I was having two elements of the exact same size and wanted to stack them. As each have same size, what I could do was to make

position: absolute;
top: 0px;
left: 0px;

on only the last element. This way the first element is inserted correctly, "pushing" the parents height, and the second element is placed on top.

Hopes this helps other people trying to stacking 2+ elements with same (unknown) height.


After much testing, I have verified that the original question is already right; missing just a couple of settings:

  • the container_row MUST have position: relative;
  • the children (...), MUST have position: absolute; left:0;
  • to make sure the children (...) align exactly over each other, the container_row should have additional styling:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; could, also, help.

Here's some reusable css that will preserve the height of each element without using position: absolute:

.stack {
    display: grid;
}
.stack > * {
    grid-row: 1;
    grid-column: 1;
}

The first element in your stack is the background, and the second is the foreground.


Of course, the problem is all about getting your height back. But how can you do that if you don't know the height ahead of time? Well, if you know what aspect ratio you want to give the container (and keep it responsive), you can get your height back by adding padding to another child of the container, expressed as a percentage.

You can even add a dummy div to the container and set something like padding-top: 56.25% to give the dummy element a height that is a proportion of the container's width. This will push out the container and give it an aspect ratio, in this case 16:9 (56.25%).

Padding and margin use the percentage of the width, that's really the trick here.


Here's another solution using display: flex instead of position: absolute or display: grid.

_x000D_
_x000D_
.container_row{_x000D_
  display: flex;_x000D_
}_x000D_
_x000D_
.layer1 {_x000D_
  width: 100%;_x000D_
  background-color: rgba(255,0,0,0.5);  // red_x000D_
}_x000D_
_x000D_
.layer2{_x000D_
  width: 100%;_x000D_
  margin-left: -100%;_x000D_
  background-color: rgba(0,0,255,0.5);  // blue_x000D_
}
_x000D_
<div class="container_row">_x000D_
    <div class="layer1">_x000D_
        <span>Lorem ipsum...</span>_x000D_
    </div>_x000D_
    <div class="layer2">_x000D_
        More lorem ipsum..._x000D_
    </div>_x000D_
</div>_x000D_
<div class="container_row">_x000D_
    ...same HTML as above. This one should never overlap the .container_row above._x000D_
</div>
_x000D_
_x000D_
_x000D_


Actually this is possible without position absolute and specifying any height. All You need to do, is use display: grid on parent element and put descendants, into the same row and column.

Please check example below, based on Your HTML. I added only <span> and some colors, so You can see the result.

You can also easily change z-index each of descendant elements, to manipulate its visibility (which one should be on top).

_x000D_
_x000D_
.container_row{_x000D_
  display: grid;_x000D_
}_x000D_
_x000D_
.layer1, .layer2{_x000D_
  grid-column: 1;_x000D_
  grid-row: 1;_x000D_
}_x000D_
_x000D_
.layer1 span{_x000D_
  color: #fff;_x000D_
  background: #000cf6;_x000D_
}_x000D_
_x000D_
.layer2{_x000D_
  background: rgba(255, 0, 0, 0.4);_x000D_
}
_x000D_
<div class="container_row">_x000D_
    <div class="layer1">_x000D_
        <span>Lorem ipsum...<br>Test test</span>_x000D_
    </div>_x000D_
    <div class="layer2">_x000D_
        More lorem ipsum..._x000D_
    </div>_x000D_
</div>_x000D_
<div class="container_row">_x000D_
    ...same HTML as above. This one should never overlap the .container_row above._x000D_
</div>
_x000D_
_x000D_
_x000D_


I had to set

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

.ElementOne, .Container ,.ElementTwo{
    width: 283px;
    height: 71px;
}

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

Use can use z-index to set which one to be on top.