CSS: How to arrange two elements on top of each other without specifying a height?

I have two DIVs that I need to position exactly one above the other. However, when I do this, formatting gets messed 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 place these two elements on top of each other and stretch the container while stretching the content:

The top left edge of .layer2 should be exactly aligned with 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; } 
+65
css
Jul 21 '11 at 18:08
source share
8 answers

First of all, you really must include position on absolutely positioned elements or you will encounter odd and confusing behavior; you probably want to add top: 0; left: 0 top: 0; left: 0 in CSS for both of your absolutely positioned elements. You will also want to have position: relative on .container_row if you want absolutely positioned elements to be placed relative to their parent and not the body of the document :

If the element has "position: absolute", the containing block is set by the closest ancestor with the "position" of "absolute", "relative" or "fixed" ...

Your problem is that position: absolute removes elements from the regular stream :

It is completely removed from the normal flow (it does not affect subsequent brothers and sisters). An absolutely positioned box sets up a new containing block for normal flow children and absolutely (but not fixed) positioned descendants. However, the contents of an absolutely positioned element do not apply to any other fields.

This means that absolutely positioned elements do not affect the size of the parent element, and your first <div class="container_row"> will have a height of zero.

Thus, you cannot do what you are trying to do with absolutely positioned elements unless you know how tall they are (or, what is the same, you can indicate their height). If you can specify heights, you can set the same heights to .container_row and everything will be lined up; you can also put margin-top on the second .container_row to leave room for absolutely positioned elements. For example:

http://jsfiddle.net/ambiguous/zVBDc/

+70
Jul 21 '11 at 18:23
source share

Great answer: "Mu is too short." I was looking for the same thing, and after reading your post, I found a solution that matched my problem.

I had two elements of the same size and they wanted to stack them. Since each is the same size, I could do

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

only for the last item. Thus, the first element is inserted correctly, "pushes" the parent height, and the second element is placed on top.

Hopes for this help other people trying to stack 2+ elements with the same (unknown) height.

+16
Aug 17 2018-11-18T00:
source share

In fact, this is possible without an absolute position and an indication of any height. All you have to do is use display: grid on the parent element and put the descendants on the same row and column.

Please check the example below based on your HTML. I added only <span> and a few colors so you can see the result.

You can also easily change the z-index each of the descendant elements to control its visibility.

 .container_row{ display: grid; } .layer1, .layer2{ grid-column: 1; grid-row: 1; } .layer1 span{ color: #fff; background: #000cf6; } .layer2{ background: rgba(255, 0, 0, 0.4); } 
 <div class="container_row"> <div class="layer1"> <span>Lorem ipsum...</span> </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> 
+7
Aug 21 '18 at 12:48
source share

I had to install

Container_height = Element1_height = Element2_height

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

Usage can use z-index to determine which one should be on top.

+3
Jan 20 '17 at 12:19
source share

Due to the absolute positioning that removes elements from the position of the document flow: absolute is not the right tool for the job. Depending on the exact layout you want to create, you will be able to use negative margins, position: relative, or maybe even convert: translate. Show us an example of what you want to do, we can help you.

+2
Jul 21 '11 at 18:31
source share

Of course, the problem is to regain your growth. But how can you do this if you do not know the height in advance? Well, if you know what proportion you want to give the container (and keep it responsive), you can regain your height by adding an addition to the other 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 width of the container. This will push out the container and give it an aspect ratio, in this case 16: 9 (56.25%).

Filling and markup uses a percentage of the width, which is really a trick.

+1
Jan 13 '14 at 17:40
source share

After much testing, I confirmed that the original question is already right; only a couple of settings are missing:

  • container_row MUST have position: relative;
  • children (...) MUST have position: absolute; left:0; position: absolute; left:0; position: absolute; left:0; to the right position: absolute; left:0; position: absolute; left:0;
  • so that children (...) are aligned exactly on top of each other, container_row should have an additional style:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; could also help.
0
Feb 17 '18 at 15:41
source share

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

 .container_row{ display: flex; } .layer1 { width: 100%; background-color: rgba(255,0,0,0.5); // red } .layer2{ width: 100%; margin-left: -100%; background-color: rgba(0,0,255,0.5); // blue } 
 <div class="container_row"> <div class="layer1"> <span>Lorem ipsum...</span> </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> 
0
Sep 22 '18 at 7:58
source share



All Articles