10

I want a child div with a op-margin via percentage. The y-position shall be 50% percent of the parent div. But it is somehow more. Why isn't it 50% ?

js fiddle

HTML

<div class="content">
  <header></header>
</div>

CSS

.content {
  width: 300px;
  height: 200px;
  background: blue;
  position: relative;
  clear: both;
 }

.content header {
   width: 100px;
   height: 100px;
   margin-top: 50%;
   background: red;
   position: relative;
   float: left;
}
user2952265
  • 1,590
  • 7
  • 21
  • 32

2 Answers2

22

This is because when it comes to top/bottom margins and paddings in percentages, the values will be taken as the fractional width of the parent element, not the height. According to the W3C definition:

The [margin] percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1.

This question has been addressed before in StackOverflow - see here.


Suggestion: If you would want to position an element in the center vertically, you can use the following trick instead:

  1. Position the child element absolutely
  2. Declare dimensions for the parent, such that the parent's dimensions do not rely on those of the child
  3. Position the child element 50% from the top
  4. Use a nifty trick of CSS 2D translation.

Here's the modified CSS from your fiddle that works:

.content header {
    width: 100px;
    height: 100px;
    top: 50%;
    background: red;
    position: absolute;
    -webkit-transform: translate(0, -50%);
    transform: translate(0, -50%);
}

http://jsfiddle.net/teddyrised/73xkT/7/

Community
  • 1
  • 1
Terry
  • 63,248
  • 15
  • 96
  • 118
  • 11
    What. _Why_ would _anyone_ think that a vertical margin should be calculated from the horizontal parent width. I really can't see a use case to ever warrant that being a good idea – Bojangles Dec 14 '13 at 16:45
  • 1
    @Bojangles You'll have to take that up with W3C :P but the postulation (see linked SO answer in my answer above) is that if we calculating top/bottom margins by height, it would lead to an infinite loop because the rendering engine will have to continuously adjust and recalculating the parent height. – Terry Dec 14 '13 at 16:46
  • 1
    @Bojangles: https://stackoverflow.com/questions/7386353/why-does-the-page-width-affect-margin-top50-in-firefox/7386385#comment8924992_7386385 (comment on another duplicate question) – BoltClock Dec 14 '13 at 16:47
5

Change child's position from relative to absolute.
Instead of margin-top use top

http://jsfiddle.net/73xkT/5/

.content header {
  top: 50%;
  position: absolute;
}
m59
  • 43,214
  • 14
  • 119
  • 136
VenomVendor
  • 15,064
  • 13
  • 65
  • 96