Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS - Position absolute is affected by sibling's margins

I have a element which is absolute positioned, relative to parent. However, the position is affected by a sibling element which has a vertical margin. Why does the absolutely positioned element, in-spite having property top equals zero, start from the same position as the sibling element which has vertical margins on it.

Please see this Codepen.

In the codepen above, the element div.b is absolutely positioned, however it is affected by sibling element div.a. The element div.a has vertical margin applied to it.

<div class="parent">
    <div class="a">
        <div class="childA"></div>
        <div class="childA"></div>
        <div class="childA"></div>
        <div class="childA"></div>
    </div>
    <div class="b"></div>
</div>

CSS:

body {
    padding: 0;
    margin: 0;
}

.parent {
    position: relative;
    width: 100%;
    height: 100%;
    background-color: blue;
}

.a {
    margin: 50px;
}

.childA {
    width: 30px;
    height: 30px;
}

.b {
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: red;
    top: 0;
} 
like image 916
Kayote Avatar asked Nov 06 '25 03:11

Kayote


2 Answers

This is a bit tricky, but when an element doesn't have any padding, the margins of its children are able to spill out beyond the contents of the container. This is referred to as collapsing margins and happens regardless of whether or not you're using position: (relative|absolute).

.block {
  height: 50px;
  background: #ccc;
}

.parent {
  background: #900;
}

.child {
  margin: 40px 0;
  background: #600;
  color: #fff;
  padding: 20px;
}
<div class="block"></div>
<div class="parent">
  <div class="child">Child</div>
</div>
<div class="block"></div>

Note that the .parent does not have a margin or padding, but there is a gap between .child and .block elements.

Typically when this behavior is undesirable you're better served by padding than margins, which also allows your background fill to continue to the edge of the spacing.

like image 160
coreyward Avatar answered Nov 09 '25 09:11

coreyward


Because, as you said in your question, it is positioned relative to its parent. relative positioned elements create a new stacking context for their children. Either move .b out of it's parent or remove position" relative; from the parent

body {
    padding: 0;
    margin: 0;
}

.parent {
    width: 100%;
    height: 100%;
    background-color: blue;
}

.a {
    margin: 50px;
}

.childA {
    width: 30px;
    height: 30px;
}

.b {
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: red;
    top: 0;
} 
<div class="parent">
    <div class="a">
        <div class="childA"></div>
        <div class="childA"></div>
        <div class="childA"></div>
        <div class="childA"></div>
    </div>
    <div class="b"></div>
</div>
like image 36
Laif Avatar answered Nov 09 '25 09:11

Laif



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!