Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do absolute elements stack up on each other instead of stacking one after the other?

How can get both #row1 and #row2 in the following code to be visible, one after the other vertically, as if there wasn't any absolute/relative positioning involved (though without removing the positioning properties)? I.e. having the two .row <div> to appear as "normal" block elements.

body { position:relative; min-height: 2em; width: 100%; }
.container {position:absolute;}
.row {position:relative;}
.col1, .col2 {position: absolute;}
<body>
  <div class="container">
    <div id="row1" class="row">
      <div class="col1">Hello</div>
      <div class="col2">World</div>
    </div>
    <div id="row2" class="row">
      <div class="col1">Salut</div>
      <div class="col2">le monde</div>
    </div>
  </div>
</body>

(Sample also available as a fiddle.)

I need the elements to have the positioning provided in the CSS rules, for reasons excluded here.

The content is programmatically dynamic; I don't know the elements' heights beforehand, so a solution can't be based on specifying an absolute length (e.g. 'px') anywhere.

like image 888
Fellow Stranger Avatar asked Dec 21 '13 11:12

Fellow Stranger


People also ask

How do you make elements stack on top of each other?

Using CSS position property: The position: absolute; property is used to position any element at the absolute position and this property can be used to stack elements on top of each other. Using this, any element can be positioned anywhere regardless of the position of other elements.

What is stacking of elements?

The stacking context is a three-dimensional conceptualization of HTML elements along an imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes.

How do you move positions with absolute elements?

Absolute Positioning You can use two values top and left along with the position property to move an HTML element anywhere in the HTML document. Move Left - Use a negative value for left. Move Right - Use a positive value for left. Move Up - Use a negative value for top.

Can you stack DIVS?

You can use the CSS position property in combination with the z-index property to overlay an individual div over another div element. The z-index property determines the stacking order for positioned elements (i.e. elements whose position value is one of absolute , fixed , or relative ).


2 Answers

Well you have some weird wishes here so let me explain you what those positions really mean in CSS and how they work, using position: relative; is just like using static position, the difference is making an element position: relative;, you will be able to use top, right, bottom and left properties, though the element will move, but physically it will be in the document flow..

enter image description here

Coming to position: absolute;, when you make any element position: absolute;, it gets out of the document flow, hence, it has nothing to do with any other element, so in your example you have .col1, .col2 {position: absolute;} which are positioned absolute and since both are out of the document flow, they will overlap... Because they are already nested under position: absolute; parent i.e .container and since no width is assigned, it will take the minimal width and hence, your elements overlap, if you cannot change your CSS(which according to me doesn't make any sense why you can't change) still if you want, than you can do is this..

Demo (Without removing any of your position property) And this is really dirty


For the s characters, it will be at the top as your container element is out of the flow, and hence, no height will be considered in the document flow, unless and until you wrap that s in some element, and bring it down with, margin padding or CSS Positioning.


CSS Positions Explained

As I commented, here are few examples of how CSS Positioning actually works, to start with, there are 4 values for position property i.e static which is the default one, relative, absolute and fixed, so starting with static, nothing to learn much here, elements just stackup one below the other unless they are floated or made display: inline-block. With static positioning, top, right, bottom and left won't work.

Demo


Coming to position: relative; I've already explained you in general, it's nothing but same as static, it stacks up on other element, it is in the document flow, but you can tweak the elements position using top, right, bottom and left, physically, the element stays in the flow, only position of the element is changed.

Demo 2


Now comes absolute which generally many fails to understand, when making an element absolute it gets out of the document flow, and hence it stays independent, it has nothing to do with other elements positioning unless it's overlapped by other position: absolute element which can be fixed using z-index to change the stack level. The main thing to remember here is to have a position: relative; container so that your absolute positioned element is relative to that relative positioned element, else your element will fly out in the wild.

It's worth noting that position: absolute; element when positioned absolute; inside an absolute positioned parent element, than it is relative to that element and not relative to the grand parent element which may be positioned relative

Demo 3 (Without position: relative; container)

Demo 4 (With position: relative; container)


Last is position fixed, this is same as absolute but it flows along when you scroll, it's out of the document flow, but it scrolls, also, position: fixed; element cannot be relative to any container element having any type of position, not even relative, position fixed element is always relative to the viewport, so designers use position: absolute; when they want to have a fixed position behavior but relative to parent and tweak the top property onScroll.

Demo 5

like image 83
Mr. Alien Avatar answered Oct 12 '22 04:10

Mr. Alien


What you want, is not possible without modifying the CSS position property. However, what you can do without touching the existing CSS, is overriding it with a more specific selector

.row .col1, .row .col2 {
    position: relative;
}

See JSFiddle

like image 2
Olaf Dietsche Avatar answered Oct 12 '22 05:10

Olaf Dietsche