0

I would like to create a conainer element, which is at least the height of the page. I set it like this: min-height: 100vh

The body has no margin.

For some reason, an empty space appears under the element. How is it possible to eliminate that?

I can observe this error in Chrome and Edge, but not in Firefox.

My code:

body {
  margin: 0;
  background: red;
}

.container {
  margin: auto;
  max-width: 200px;
  background: gray;
  min-height: 100vh;
  box-sizing: border-box;
}

.item {
  background: white;
  margin-bottom: 1em;
  height: 100px;
}
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>

This is how it looks like:

chrome

Nazim Kerimbekov
  • 4,712
  • 8
  • 34
  • 58
Iter Ator
  • 8,226
  • 20
  • 73
  • 164
  • add some padding on container (1px) , for some reasons, margin-bottom on item jumps outside the container https://jsfiddle.net/z8tg1746/ or remove the margin on the last item https://jsfiddle.net/ahm9yqoL/ – G-Cyrillus May 15 '19 at 18:26
  • The reason you're seeing that is because of the height 100 percent, the 100 percent does not always work as expected , you will have to use either JavaScript for your height, or a combination of display type flex for the height – Dev Man May 15 '19 at 18:26
  • 1
    about margins jumping out : https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing **Parent and first/last child** *`If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of its first child block; or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block from the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.`* – G-Cyrillus May 15 '19 at 18:54
  • @G-Cyr yet another strange case of margin collapsing: https://stackoverflow.com/q/48777787/8620333 – Temani Afif May 15 '19 at 20:20
  • 1
    The duplicate question is more generic than this one. The answer explain why both FF and Chrome behave differently and you will also find the relevant part of the specification to describe all this – Temani Afif May 15 '19 at 20:23
  • @TemaniAfif i think it's a small bug since it happens not in every browsers and caring about margin collapsing cures it. Agreed that it should not happen before the margin value is bigger than the space left in the parent. For me it is an unexpeted behavior that is easily taken care of. nothing to compare of what MSIE 6 use to be ;) – G-Cyrillus May 15 '19 at 21:43
  • @G-Cyr it's not really a bug because it's defined in the spec (`bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height`) and FF is somehow violating that spec (like Bolt is explaining in my question) but yes it's counter intuive and should probably change. – Temani Afif May 15 '19 at 21:48

5 Answers5

1

You can get it to work by removing the margin of the last .item element.

body {
  margin: 0;
  background: red;
}

.container {
  margin: auto;
  max-width: 200px;
  background: gray;
  min-height: 100vh;
  box-sizing: border-box;
}

.item {
  background: white;
  margin-bottom: 1em;
  height: 100px;
}
.item:last-child { 
  margin:0;
}
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>
Vikram Deshmukh
  • 12,304
  • 4
  • 36
  • 38
  • 1
    The margin is not the issue , but rather the extra space that is left after the margin – Dev Man May 15 '19 at 18:36
  • @ImmortalDude, agreed! Your solution of using the flexbox is the correct approach. – Vikram Deshmukh May 15 '19 at 18:38
  • @ImmortalDude the margin seems to be the BUG https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing .. agreed it should not happen here, but it does and removing it cures the issue – G-Cyrillus May 15 '19 at 18:42
  • @G-Cyr a simple reset applied to the html and body elements also fixes the issue, no need to remove the margin from the element – Dev Man May 15 '19 at 19:13
1

The issue is caused by the .container margin to center with auto and the .item children having a bottom margin. For some reason the causing a lack of collapse which is, in turn, causing the margin to overflow (or append to) it's owner, even if margin-bottom: 0 is applied to .container.

To resolve this, we have come up with a different way, by not using margin: auto;, of centering the .container.

As well as, to force a collapse by setting a height relationship between culprit of the overflow and it's parent. We will accomplish this by setting height: 100%; to html, body.

I will propose three solutions which solve the display discrepancy.

Option 1

Edit: This solution does not seem to be consistent to me in Edge upon further testing. Sometimes I have to open DevTools and toggle min-height: 100vh; in .container to get it to render correctly.

html, body {
  height: 100%;
}

.container {
  /* Remove the margin */
  /* margin: auto; */
  position: relative;
  left: 50%;
  transform: translateX(-50%);

This fixes the issue in Edge and Chrome. To answer the question, this is the only edit required.

jsFiddle

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: red;
}

.container {
  position: relative;
  left: 50%;
  transform: translateX(-50%);

  min-height: 100vh;
  max-width: 200px;
  background: grey;
}

.item {  
  position: relative;
  margin-bottom: 1em;
  height: 100px;
  background: white;
}
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>

Option 2

This method is a slight modification to how the .item margin is applied where we will apply to all .item's except the last one using :not(last-child).

jsFiddle

html, body {
  height: 100%;
}

body {
  margin: 0;
  background: red;
}

.container {
  margin: auto;
  min-height: 100vh;
  max-width: 200px;
  background: grey;
}

.item {  
  position: relative;      
  height: 100px;
  background: white;
}

.item:not(:last-child) {
  margin-bottom: 1em;
}
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>

Option 3

If you're familiar with Flexbox, you could solve it that way with the following edits to your CSS:

body {
  margin: 0;
  background: red;

  display: flex;
  flex-direction: column;
  justify-content: center;
}

.container {
  /* Without a min height set the width 
  /*   will default to the content's width */
  /* max-width: 200px; */
  width: 200px;
  
  margin: auto;
  background: gray;
  min-height: 100vh;
  box-sizing: border-box;
}

.item {  
  position: relative;
  margin-bottom: 1em;
  height: 100px;
  background: white;
}
<body>
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>
</body>

Here, we set body as flexbox, set as column direction, and center the content (direct children).

Importantly, we have to set a minimum width so that if our content is less than 200px it won't get squished.

seantunwin
  • 1,698
  • 15
  • 15
0

You can just set height: 100% on the container for it to be the height of the page at all times.

beznet
  • 532
  • 1
  • 5
  • 13
0

The below modified code should help you. Set margin: 0 in the html and body elements

html, body { /* or use * to apply this margin reset to all elements */
  margin :0;
}

body{
  background: red;
}

.container {
  margin: auto;
  max-width: 200px;
  background: gray;
  
  height:100vh;
  box-sizing: border-box;
}

.item {
  background: white;
  margin-bottom: 1em;
  height: 100px;
}
<div class="container">
  <div class="item">...</div>
  <div class="item">...</div>
  <div class="item">...</div>
</div>
Dev Man
  • 2,114
  • 3
  • 23
  • 38
  • ?? container is supposed to be at the minimum 100vh height showing a background till the bottom. it does not anymore – G-Cyrillus May 15 '19 at 18:49
  • @G-Cyr updated the answer as I misunderstood what was the issue – Dev Man May 15 '19 at 19:11
  • the op had already set margin:0 to body , he has this 1em extra outside the container in chrome and edge only, this should happen only when the last item reaches the bottom of the container. vertical margins are shown outside containers if no borders,padding or block formatting context is set . The problem here is that it happens even if there is more than 1em free space in the .container below the last item. – G-Cyrillus May 15 '19 at 19:25
  • Not just body but also html, that is what removed the issue on my browsers "chrome 74", the op has not included the margin 0 to the html as well – Dev Man May 15 '19 at 19:27
  • okay, i did not expect this , funny – G-Cyrillus May 15 '19 at 19:27
  • @G-Cyr, yeah , I didn't have this problem as I always apply margin, padding, border, outline, font-size resets to all my elements , didn't know that something like that existed, learned something from a question as opposed to an answer – Dev Man May 15 '19 at 19:30
  • hmmm, not working with my chrome https://jsfiddle.net/pmvy4q1t/ **Version 74.0.3729.131 (Build officiel) (64 bits)** – G-Cyrillus May 15 '19 at 19:33
  • @G-Cyr, quite odd, it seems to work perfectly in mine – Dev Man May 15 '19 at 19:35
  • mysteries of the internet :) – G-Cyrillus May 15 '19 at 19:36
  • 1
    @G-Cyr, I will get back to you, if I find anything – Dev Man May 15 '19 at 19:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/193422/discussion-between-immortal-dude-and-g-cyr). – Dev Man May 15 '19 at 19:47
-3

You might try to add some padding to your .item