162

I want to use a full-height app using flexbox. I found what I want using old flexbox layout module (display: box; and other things) in this link: CSS3 Flexbox full-height app and overflow

This is a correct solution for browsers that only support the old version of the flexbox CSS properties.

If I want to try using the newer flexbox properties, I'll try to use the second solution in the same link listed as a hack: using a container with height: 0px;. It makes to show a vertical scroll.

I don't like it a lot because it introduces other problems and it is more a workaround than a solution.

html, body {
    height: 100%;    
}
#container {
 display: flex;
 flex-direction: column;
 height: 100%;
}
#container article {
 flex: 1 1 auto;
 overflow-y: scroll;
}
#container header {
    background-color: gray;
}
#container footer {
    background-color: gray;
}
<section id="container" >
    <header id="header" >This is a header</header>
    <article id="content" >
        This is the content that
        <br />
        With a lot of lines.
        <br />
        With a lot of lines.
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
    </article>
    <footer id="footer" >This is a footer</footer>
</section>

I have prepared a JSFiddle as well with a base example: http://jsfiddle.net/ch7n6/

It is a full-height HTML website and the footer is at the bottom because of the flexbox properties of the content element. I suggest you move the bar between CSS code and result to simulate different height.

TylerH
  • 20,799
  • 66
  • 75
  • 101
José Cabo
  • 6,149
  • 3
  • 28
  • 39
  • 1
    This isn't the behavior you're looking for? http://jsfiddle.net/ch7n6/2/ – cimmanon Feb 19 '13 at 17:59
  • 2
    http://jsfiddle.net/ch7n6/3/ Yes! It is. :D But I can't understand why I need to indicate a height to obtain the effect. Anyway setting: **height: 1px;** works – José Cabo Feb 19 '13 at 18:24
  • Now I changed the height to a min-height. Much better. Thanks you. – José Cabo Feb 19 '13 at 18:27
  • 1
    @JoséCabo +1 - nice trick height:0 to show vertical scroll! Could you explain **why** this works? – Danield Jun 24 '13 at 23:22
  • My answer to my question (the second answer for this question) I do my best to explain it. In reality what you want to do is use min-height instead of height for a "semantic" answer... but in reality is what the standard said. – José Cabo Jun 25 '13 at 17:06
  • Dear @MikePhils, have you read this post? – José Cabo Jul 18 '15 at 21:39
  • 1
    You should apply `flex-shrink:0` to both header and footer. – Saorikido Jul 20 '15 at 02:42
  • @Z.Neeson Yes, you are right. Perhaps I should update the question's answer to change the flex: auto and set it to 0 (or the right value). The thing is that at that time my flex knowledge was not as good as today. – José Cabo Jul 20 '15 at 11:23

3 Answers3

333

Thanks to https://stackoverflow.com/users/1652962/cimmanon that gave me the answer.

The solution is setting a height to the vertical scrollable element. For example:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 0px;
}

The element will have height because flexbox recalculates it unless you want a min-height so you can use height: 100px; that it is exactly the same as: min-height: 100px;

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 100px; /* == min-height: 100px*/
}

So the best solution if you want a min-height in the vertical scroll:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 100px;
}

If you just want full vertical scroll in case there is no enough space to see the article:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0px;
}

The final code: http://jsfiddle.net/ch7n6/867/

TylerH
  • 20,799
  • 66
  • 75
  • 101
José Cabo
  • 6,149
  • 3
  • 28
  • 39
  • 7
    Using `min-height`in Chrome does not work, it affects the size of the footer somehow. Using `height` however, gives the desired result. – phant0m Jun 25 '15 at 21:58
  • 1
    Try to place that heigh in where the "auto". I have studied this and I think the right place is this property. So instead of using min-height and height use it. – José Cabo Jul 02 '15 at 15:29
  • `height: 0` fixed some 2px jumping when content is overflowing vs when it's not. So weird. Thanks anway. – ProblemsOfSumit Mar 10 '16 at 15:04
  • @Sumit, can you provide a picture of what problem are you facing? – José Cabo Mar 10 '16 at 15:51
  • I opened the fiddle link and doesn't seem to be working anymore on Chrome (works in Firefox). The scroll bar disappeared. Does anyone have an idea how to get this working again? – bets Apr 03 '17 at 20:47
  • The scroll bar is there but invisible. That has to do nothing with the css flexbox but with the style that Chrome is applying. Do scroll and you will see the scroll bar appear. Tested with latest Chrome version in macOS. – José Cabo Apr 05 '17 at 15:08
  • This does not hide the address bar in Chrome – Richard Lindhout Jul 21 '17 at 12:57
  • @RichardLindhout the address bar is never mentioned in the question as any type of requirement, why do you bring it up? – Erik Philips Nov 20 '17 at 23:30
  • @ErikPhilips because it's a disadvantage of this solution, could be interesting to know for some users. especially when you're building a mobile website, the address bar is a lot of space for some of the mobile screens. – Richard Lindhout Nov 28 '17 at 09:45
  • nvm I wasn't setting the html height to 100% only the body. Makes perfect sense – gyozo kudor Aug 28 '20 at 09:29
  • My content is hidden, `height: 0px;` is not dynamically changed... I got a 0-height box :D – Virinas-code Mar 22 '22 at 14:58
  • I'll never understand CSS. But hey, it works a charm! Thanks for preventing me pulling my hear out! – xorinzor Jun 11 '22 at 09:09
80

Flexbox spec editor here.

This is an encouraged use of flexbox, but there are a few things you should tweak for best behavior.

  • Don't use prefixes. Unprefixed flexbox is well-supported across most browsers. Always start with unprefixed, and only add prefixes if necessary to support it.

  • Since your header and footer aren't meant to flex, they should both have flex: none; set on them. Right now you have a similar behavior due to some overlapping effects, but you shouldn't rely on that unless you want to accidentally confuse yourself later. (Default is flex:0 1 auto, so they start at their auto height and can shrink but not grow, but they're also overflow:visible by default, which triggers their default min-height:auto to prevent them from shrinking at all. If you ever set an overflow on them, the behavior of min-height:auto changes (switching to zero rather than min-content) and they'll suddenly get squished by the extra-tall <article> element.)

  • You can simplify the <article> flex too - just set flex: 1; and you'll be good to go. Try to stick with the common values in https://drafts.csswg.org/css-flexbox/#flex-common unless you have a good reason to do something more complicated - they're easier to read and cover most of the behaviors you'll want to invoke.

Xanthir
  • 18,065
  • 2
  • 31
  • 32
  • flex: none; saved me It was what helped me have a flex element take the entire height of its children and ignore the height 100% of its parent (had 100% on a parent in order to use overflow) – CatalinBerta Oct 12 '20 at 09:04
22

The current spec says this regarding flex: 1 1 auto:

Sizes the item based on the width/height properties, but makes them fully flexible, so that they absorb any free space along the main axis. If all items are either flex: auto, flex: initial, or flex: none, any positive free space after the items have been sized will be distributed evenly to the items with flex: auto.

http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#flex-common

It sounds to me like if you say an element is 100px tall, it is treated more like a "suggested" size, not an absolute. Because it is allowed to shrink and grow, it takes up as much space as its allowed to. That's why adding this line to your "main" element works: height: 0 (or any other smallish number).

cimmanon
  • 67,211
  • 17
  • 165
  • 171