1

In this example, as soon as the browser window height drops below 400px, the image is no longer centered in the scrollable area.

 html {
   height: 100%;
 }
 
 body {
   height: 100%;
   display: flex;
   align-items: center;
   margin: 0;
   padding: 0;
 }
 
 #content {
   height: 400px;
   display: flex;
   align-items: center;
 }
<div id="content">
  <img src="http://placehold.it/300x300">
</div>

It works as soon as I unset the height property of the html or of the body or of both.

Still, I want to understand why centering in this specific example fails. Does it have something to do with the nested flexboxes? Or is there something problematic with setting the height of both, html and body, to 100%? Is it a bug or something browser related?

fweth
  • 631
  • 6
  • 16
  • You know you have a container of height 400px in the body, so you know that your body cannot be shorter than 400px - add a min-height of 400px on html,body. Interestingly, when you take display: flex off the body and have a body shorter than 400px, then it works, so it has something to do with #container being a flex child of a container shorter in height than itself.... – Adam Jenkins Oct 13 '16 at 23:09
  • Here's something cool - replace `height:100%` with `min-height: 100%` on the `body` and it works at all heights! – Adam Jenkins Oct 13 '16 at 23:17

1 Answers1

1

It's similar to margin: 0 auto (in conjunction with position: relative) for horizontal centering: As long as the container is wider than the centered child, the child will be centered. But as soon as the container (or the body/viewport) is narrower than the child, the child will be aligned left and a scrollbar will appear. That way it will always possible to see the whole child element - since it's larger than the container, that only is possible when scrolling is enabled.

In the situation you describe, the same happens with flexbox and vertical centering: If the parent container would be smaller (i.e. less high) than the child, and the child would be centered without a scrollbar, you wouldn't be able to see it's top and bottom part (which can be important for example if it's a form where you have to fill in text fields etc.), and you wouldn't be able to scroll to see those hidden parts. So in this situation (child higher than parent with child vertically centered in flex container), the child will be put at the top of the parent and you will be able to scroll down, which is good to either read/see the whole content or see/fill in the whole form in case of forms.

Johannes
  • 64,305
  • 18
  • 73
  • 130