I got an awesome incognita to share with you. I found it while trying to do a very simple thing - at least i thought it was simple.
The Stage
A parent element with a fixed height value which contains any number of child. Let's put divs as example, starting with 2 childs.
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
The Goal
Style the child's height and vertical margin to match exactly the parent height, dividing the total height equally among the child elements. The solution should be reusable for any number of child elements. Of course some kind of calculation could be needed.
The problem
Using percentage-based height and margin don't works. Any solution like the following...
.parent {
width: 5em; /* some fixed width */
height: 10em; /* some fixed height */
}
.child {
width: 100%;
margin-top: 4%;
height: 44%; /* let's render 3 gaps of 4% each (on top, middle and bottom) */
}
... will fail to render as expected because the vertical margin - and padding too - resolved values are based on parent's width, not parent's height as you may expect. This jsfiddle demonstrates this behaviour with the following tests:
Test 1
Set a margin-top and margin-bottom. Child's height is set to 100% - @margin-top - @margin-bottom
Case A
Parent's height is higher than its width. The browser renders a gap on the bottom of the parent because of the mentioned problem.
Case B
Parent's height is equal than its width. The browser renders as expected because parent's width is equal to the parent's height and the margin is resolved correctly:
@parent-width = @parent-height
@base = @parent-width
Case C
Parent's height is lower than its width. The second child is clipped because of the mentioned problem.
Test 2
This test cases demonstrate the padding behaviour as the test 1 does with the margin.
Test 3
Demonstrates that the child's height is resolved from parent's height. The browser renders all cases as expected if we don't try to put some margin or padding.
Test 4
This test is intended to be useful if you want to research an answer for the second question - see below
The questions
- Why are vertical height and padding based on parent's width rather than parent's height? I couldn't find anything on the w3c specs.
- What is the better posible solution to reach the desired goal?
Today I stumpled upon the same problem and I found the new relative unit vh (CSS 3) very helpful in this case: It works like percent, but relative to the height of the viewport (use vw for relative width). This is a pure CSS solution if the relativity to the viewport instead of to the parent is not an issue.
Interesting... but I think the problem isn't about vertical height, they all displayed correctly on my browser (height was always relative to parent's height), it is padding and margin that measure to parent's width always, after research though, I found this:
http://www.w3.org/wiki/The_CSS_layout_model_-_boxes_borders_margins_padding
Good catch, I never knew :)