George Oblapenko
George Oblapenko

Reputation: 878

Percentage based margin-top and height are not working together

Here's the JSFiddle link. And here's the CSS code:

body, html {
    background-color: #EAEAEA;
    height: 100%;
    margin-right: 0;
    margin-left: 0;
    padding-right: 0;
    padding-left: 0;
    padding-top: 0;
    margin-top: 0;
    overflow: hidden;
}

.a {
    position: absolute;
    height: 13%;
    background-color: #070000;
    width: 86%;
}
.b {
    position: absolute;
    height: 86%;
    background-color: #FF0000;
    width: 13%;
    margin-left: 87%;
}
.c {
    position: absolute;
    height: 86%;
    margin-top: 14%;
    background-color: #00FF00;
    width: 13%;
}
.d {
    position: absolute;
    height: 13%;
    margin-top: 87%;
    background-color: #0000FF;
    width: 86%;
    margin-left: 14%;
}

I've been making a page with 4 elements, and the problem I've encountered is that when resizing the browser window, the width of the elements (and the margin between them) change as I expect, but for some reason, the elements can start overlapping vertically, even though, for example, the height of the black element (div class a) is 13%, the height of the green element is 86 (div class c)%, and the green element has an absolute position and margin-top value of 14%.

The blue element (div class d) can become positioned lower than the browser window's lower edge (even though it has a margin-top of 87% and a height of 13%, it seemed logical to me that it would be situated at the very bottom of the window; not higher or lower).

What is going on? I wanted the elements to be positioned exactly at the edges of the browser window, resize automatically on window size change and not overlap). I planned on using jQuery to make the vertical and horizontal margins match. But now, I need to understand why my CSS code isn't working as expected.

Upvotes: 2

Views: 2292

Answers (3)

David Glusenco
David Glusenco

Reputation: 41

Unfortunately, percentage based margin-top values won't work because they are calculated from the width of the containing element, as previously stated.

If you need fluid, responsive, scalable margins based on width or height and can't use absolute positioning try using viewport units in your CSS. Viewport units behave very similarly to percentage based dimensions except that they are calculated from the dimensions of your viewport window and will scale and resize according to the dimensions of your browser window.

vw = Viewport Width: This measurement is based on the width of the viewport. A value of 1vw equals 1% of the viewport width.

vh = Viewport Height: This measurement is based on the height of the viewport. A value of 1vh equals 1% of the viewport height.

You can use decimals of percentages also, like so-

.container {
    margin-top: .2vw;
}

Viewport units were not very widely supported a few years ago, but all modern browsers support them now. If you familiarize yourself with them it will open up a lot more options for you.

Upvotes: 0

Josh Crozier
Josh Crozier

Reputation: 240888

If you're looking for a reason as to why this behavior is occurring:

CSS basic box model - 8. The margin properties

Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).

Emphasis added. These margin-top values are relative to the width of the body element. In this instance, if the window is resized horizontally, the heights of the elements don't change, yet the margin-top values do; resulting in vertical alignment issues.

No need to use jQuery to solve this. The solution would be to use something other than margins for displacement. See this updated example.

Upvotes: 4

badAdviceGuy
badAdviceGuy

Reputation: 2090

Instead of using margin to position your elements you should use top / left / right / bottom. So change your margin-top: 14% to just top:14%

Upvotes: 3

Related Questions