11

I must be forgetting something fundamental with my vertically and horizontally centered flexbox.

The container is within a parent with vertical scroll, and when the container becomes too tall, it grows beyond the parent top, clipping the content. The bottom stays put.

Try adjusting the height of the view or adding more lines to see it in action.

body,
html {
  height: 100%;
  width: 100%;
  margin: 0;
}

* {
  box-sizing: border-box;
}

#wrapper {
  background: grey;
  height: 100%;
  width: 100%;
  max-height: 100%;
  display: flex;
  overflow-y: auto;
  align-items: center;
  justify-content: center;
}

#box {
  margin: 30px 0;
  background: white;
  border: 1px solid #dfdfdf;
}
<div id="wrapper">
  <div id="box">
    First line
    <br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
  </div>
</div>

How do I keep it from getting clipped? Additionally I'm trying to have a 30px margin above and below the container.

Thanks!

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Jeppebm
  • 389
  • 1
  • 3
  • 16

3 Answers3

16

You forgot nothing but you simply need to understand what is happening. First you made your wrapper to be 100% height of screen and then you made the box to be centred vertically and horizontally. When the box has a big height you will have something like this:

enter image description here

Now, when you add overflow-y: auto you will create a scroll that will start from the top of the wrapper until the bottom overflowed content. So it will be like this:

enter image description here

That's why you are able to scroll to the bottom to see the bottom part and not able to see the top part.

To avoid this, use margin:auto to center your element and in this case we will have two situations:

  1. When box-height < wrapper-height we will have the space spread equally on each side because of the margin:auto thus your element will be centred like expected.
  2. When box-height > wrapper-height we will have the normal behavior and your element will overflow and his top edge will stick to the top edge of the wrapper.

enter image description here

You may also notice the same can happen horizontally that's why I will use margin to center on both directions.

body,
html {
  height: 100%;
  width: 100%;
  margin: 0;
}

* {
  box-sizing: border-box;
}

#wrapper {
  background: grey;
  height: 100%;
  width: 100%;
  max-height: 100%;
  padding:30px 0;
  display: flex;
  overflow-y: auto;
}

#box {
  margin: auto;
  background: white;
  border: 1px solid #dfdfdf;
}
<div id="wrapper">
  <div id="box">
    First line
    <br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 2
    Wow - I would never have come up with that solution. While your great explanation helps, I'm not exactly sure why the margin: auto fixes this. Any additional explanation you can provide? Thank you for your help. – Jeppebm Mar 14 '18 at 13:53
  • 1
    @Jeppebm margin:auto is one of the magic of flex ;) when you set auto means split the margin to be equal in each side which make the element centred ... excatly like margin:auto with a block element that has a fixed width ... and when the height is bigger there is no margin, so it will be useless and you have the normal behavior – Temani Afif Mar 14 '18 at 13:55
2

I think what you want is to make your flex item (#box) have a height and set it's overflow, not the flex container. Also, to add your 30px above and below I would remove the margin from the box and instead add padding to the container.

So, updated styles would look like this:

#wrapper {
  background: grey;
  height: 100%;
  width: 100%;
  max-height: 100%;
  display: flex;      
  align-items: center;
  justify-content: center;
  padding: 30px 0; /*added*/
}

#box {
  background: white;
  border: 1px solid #dfdfdf;
  overflow-y: auto; /*added*/
  height: 100%; /*added*/
}

body,
html {
  height: 100%;
  width: 100%;
  margin: 0;
}

* {
  box-sizing: border-box;
}

#wrapper {
  background: grey;
  height: 100%;
  width: 100%;
  max-height: 100%;
  display: flex;      
  align-items: center;
  justify-content: center;
  padding: 30px 0;
}

#box {    
  background: white;
  border: 1px solid #dfdfdf;
  overflow-y: auto;
  height: 100%;
}
<div id="wrapper">
  <div id="box">
    First line
    <br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
  </div>
</div>
zgood
  • 12,181
  • 2
  • 25
  • 26
0

I think you set the top margin in the box class which extends the height of the container. You can maybe set it to padding instead of margin. Hope this helps. Thanks.

Paul
  • 460
  • 2
  • 7