25

The h1 element causes a scrollbar to appear. Can anyone explain me why?

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}
header {
  height:10%;
}
section {
  height:90%;
}
<header>
  <h1>
    Hello
  </h1>
</header>
<section>
  test
</section>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Matthew
  • 10,988
  • 11
  • 54
  • 69

5 Answers5

18

That's because

  • h1 have some vertical margin by default, usually 0.67em.
  • The top margin of h1 collapses
  • height never includes the height of the margin area

Since the top margin of h1 collapses, it behaves like the margin belonged to the header instead of the h1. Since the content height of the h1 is 10%, its total height will be calc(10% + 0.67em).

That's why there is overflow.

If you remove the top margin but leave the bottom one there is no problem, because the bottom one does not collapse, due to the non-auto height. From Collapsing margins,

Two margins are adjoining if [...] both belong to vertically-adjacent box edges, [... e.g.]

  • top margin of a box and top margin of its first in-flow child
  • bottom margin of a last in-flow child and bottom margin of its parent if the parent has auto computed height.

So you can do any of the following

  • Remove h1's top margin
  • Prevent the margin collapse
  • Propose a box-sizing: margin-box to the CSS Working Group. It will probably be rejected.
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 1
    this is actually the best answer. But some questions: how can a margin collapse if I have only one element with margin? Second, which solution do you recommended among your suggestions? – Matthew Jul 30 '16 at 18:08
  • I mentioned `margin-bottom` because in many (most?) cases there will be elements below an `h1`. The question I assume provided a highly simplified example. In actual use, the `margin-bottom` may have an impact. But I agree that only `margin-top` matters in this case. – Michael Benjamin Jul 30 '16 at 18:09
  • @Matthew If you don't need the margin, I would remove it. Otherwise I would use `h1{ display: inline-block }` or similar to prevent margin collapse. – Oriol Jul 30 '16 at 18:11
  • 1
    @Michael_B Yes, if there was some content after the `h1`, the `margin-bottom` would still increase the distance between them. I didn't mean it's completely ignored. – Oriol Jul 30 '16 at 18:14
  • @Oriol can you explain me how margin collapse if only one element has margin (h1). Which margins are collpasing? margin-top of h1 element with what? – Matthew Jul 30 '16 at 18:16
  • 1
    The top margins of `h1` and `header` collapse. So the behavior will be like if `h1` had no top margin, and `header` had a top margin equal to the maximum of its top margin (0) and `h1`'s one. – Oriol Jul 30 '16 at 18:21
  • @Oriol so you consider that header HAS a top-margin, which is 0. And that it collapses with the top-margin of h1. What confused me is that for me header had just no top-margin... – Matthew Jul 30 '16 at 18:25
6

Because the h1 comes with a margin, applied by the default style sheet.

When you add this margin (often margin-top: .67em and margin-bottom: .67em) to the height: 100% in your code, this exceeds the viewport height, launching a vertical scroll bar.

Give the h1 a margin: 0.

Whether you use box-sizing: content-box or border-box, the margin space will always be added to your height declaration.

If you want to add space around your h1 without adding height, use padding instead of margin, along with box-sizing: border-box. Here are some implementation options: https://css-tricks.com/box-sizing/

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

h1 by default has a margin applied.

enter image description here

Polyov
  • 2,281
  • 2
  • 26
  • 36
  • I know that h1 has a margin. But why does it cause a scrollbar? header is 10%, and section is 90% of viewport. h1 is contained in header. – Matthew Jul 30 '16 at 17:45
1

*
{
  margin:0px auto;
}
html, body {
  margin: 0 ;
  padding: 0;
  height: 100%;
}
header {
  height:10%;
}
section {
  height:90%;
}
<header>
  <h1>
    Hello
  </h1>
</header>
<section>

  test
</section>

Just add universal selector and make the margin *{margin:0px auto;} . Hope it will work

Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
Sampad
  • 1,645
  • 11
  • 14
1

h1 tag in a block level element has some margin.

To remove such type of extra margin and padding, it is recommended to reset all elements margin and padding to 0.

This can be done by :

 * {
     margin: 0;
     padding: 0;
 }

* {
  margin: 0;
  padding: 0;
}
html, body {
  height: 100%;
}
header {
  height:10%;
}
section {
<header>
  <h1>
    Hello
  </h1>
</header>
<section>
  test
</section>
Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
Abhishek
  • 305
  • 2
  • 9