2

I have the following html:

<style>
    body {
        margin: 0;
        height: 100vh;
    }
    div {
        margin: 1px;
    }
</style>


<body>
<div>feck</div>
</body>

The div's margin causes scroll bars, even tho the div itself is nowhere near the height of the page. Without the div's margin, there is no scroll bar. What's going on? Is this a browser bug?

B T
  • 57,525
  • 34
  • 189
  • 207
  • It appears to me that it has to do with how the browser is handling VH vs doing something like `height:100%`. For example https://jsfiddle.net/cd1jztuj/8/ vs https://jsfiddle.net/cd1jztuj/4/ .. It does seem kind of odd. – khollenbeck May 21 '15 at 20:00
  • possible duplicate of [CSS Margin Collapsing](http://stackoverflow.com/questions/102640/css-margin-collapsing) – sergdenisov May 21 '15 at 20:04
  • Sergey, while both questions are related to margins, the questions are completely different. Did you read through both questions? Don't just mark things duplicate without actually using your brain please. – B T May 21 '15 at 20:45

4 Answers4

5

Collapsing margins. Because the div is the topmost element in the body, the div's margin is collapsed with the body's margin. That is, the body gets the same margin too.

You may think that "collapsing" isn't the right word for this behaviour, and you'd be right, but that's the word they've chosen. Sorry.

There are several solutions:

  • Sean's solution of simply moving the div a pixel downwards
  • Your own solution of using calc for the body height
  • Set a padding on the body, and use box-sizing:border-box for it.
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • Ugh, why does css have to be so completely unintuitive so often? I can in fact get the margins to uncollapse by putting the margin in an inner div *and* adding a border on an outer div. This in my mind is a huge design flaw - borders on inner elements like this should never be able to affect the set height of a container element. – B T May 21 '15 at 20:12
  • In any case, how can I work around this? I tried box-sizing: border-box, but that didn't help. I could calc(100vh - margins) but that seems too brittle. Any ideas? – B T May 21 '15 at 20:12
  • OK, I edited my answer, but calc is not that "brittle" any more; it works in all browsers these days. And the worst that can happen on an older browser is the vertical scrollbar! – Mr Lister May 21 '15 at 20:20
  • @BT switch the margins to padding and it should work just fine. See my answer bellow, it has a link to a more comprehensive answer on this subject and with possible solutions. – Stafie Anatolie May 21 '15 at 20:25
  • Ah box-sizing doesn't have a way to include margins, wonderful. I guess what I mean by brittle is I have to make sure if i change the margin i also change the height - which I guess for me is no big deal cause i'm generating css with a system that can use variables. The padding solution works pretty well for me. – B T May 21 '15 at 20:26
1

Because a div is a block element. It has positioning in the Dom, therefore takes up space. When you add a margin to the top, you are pushing its space down, therefore increasing the overall amount of space it occupies.

If you want to push the div down, without changing the overall container (body) height, you can give the div a position of relative, and a top of 1px.

div {
  position: relative;
  top: 1px;
}
Sean Stopnik
  • 1,868
  • 11
  • 9
  • 1
    Um, but I explicitly set the height of the body to a particular value. That value shouldn't change regardless of the contents changing. The div is the only node in the body so there is nothing to "push down" – B T May 21 '15 at 20:01
0

Check out this answer it should be clear enough.

The main point is that margins of adjacent elements (in this case your div and body) are collapsing taking the maximum value of the two margins.

Community
  • 1
  • 1
Stafie Anatolie
  • 358
  • 2
  • 12
0

try to give float:left; for div,

body {
    margin: 0;
    height: 100vh;
}
div {
    margin: 50px;
    float: left;
}
<body>
<div>feck</div>
</body>
Mohammad
  • 36
  • 3