Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<html> , <body> , padding, margin, 100vh and calc()

Tags:

html

css

Consider the following code snippet:

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  background-color: green;
  min-height: 100vh;
}
<section style="min-height: 50px; background-color: pink;"></section>

As expected, the body element fills the entire viewport in green and on top there is a section element in pink.

Now, suppose you want to do something else very simple like set a margin in the section element: style="min-height: 50px; background-color: pink; margin-bottom: 10px;". Unexpectedly, a blue strip from the html element appears in the bottom of the viewport.

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  background-color: green;
  min-height: 100vh;
}
<section style="min-height: 50px; background-color: pink; margin-bottom: 10px;"></section>

Question 1) Why this behaviour? It doesn't make sense to me.

One way to correct this behavior is including padding and min-height calc() adjustments in the body element:

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  padding-bottom: 1px;
  background-color: green;
  min-height: calc(100vh - 1px);
}
<section style="min-height: 50px; background-color: pink; margin-bottom: 10px;"></section>

However, this solution requires such a gimmick that I'm not comfortable with.

Question 2 Is there a better solution? (ie: more intuitive and more readable)

like image 600
Mark Messa Avatar asked Nov 27 '22 01:11

Mark Messa


1 Answers

You are facing a margin-collapsing issue. The bottom margin you applied to your section is collpasing with the bottom margin of the body and thus its applied to the body instead of the section.

As you can read here:

The top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the individual margins (or just one of them, if they are equal), a behavior known as margin collapsing.

Margin collapsing occurs in three basic cases:

Adjacent siblings

Parent and first/last child

Empty blocks

That's why in your case you have 10px of margin bottom that adds the scroll to your page since body has a min-height:100vh

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  background-color: green;
  min-height: 100vh;
}
<section style="min-height: 50px; background-color: pink;margin-bottom: 10px;"></section>

To avoid such behavior you need to simply avoid margin to collpase. So you can include a small padding like you did or a border then don't forget to also add box-sizing:border-box to avoid changing the height and use calc.

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  background-color: green;
  min-height: 100vh;
  border-bottom:1px solid transparent;
  /* OR padding-bottom:1px */
  box-sizing:border-box;
}
<section style="min-height: 50px; background-color: pink;margin-bottom: 10px;"></section>

You can also use flex as there is no margin collpasing with flex (check links below for more method):

html {
  margin: 0;
  padding: 0;
  background-color: blue;
}

body {
  margin: 0;
  padding: 0;
  background-color: green;
  min-height: 100vh;
  display:flex;
  flex-direction:column;
}
<section style="min-height: 50px; background-color: pink;margin-bottom: 10px;"></section>

Some links that may help you to get more information:

https://css-tricks.com/what-you-should-know-about-collapsing-margins/

How do I uncollapse a margin?

CSS margin terror; Margin adds space outside parent element

Margin on child element moves parent element

Margin collapsing in flexbox

like image 198
Temani Afif Avatar answered Dec 05 '22 03:12

Temani Afif