13

I have created a simple flexbox based page, which renders properly in Google Chrome (Version 44.0.2403.157), but not in Safari (Version 8.0.2 (10600.2.5)). I have added all of the relevant prefixes (I think) and have spent a lot of time looking at the inspector but I do not seem to have found the cause of the problem.

The page consists of a container and two flex rows. The first flex row (header) should have its height stretch to fit its content. The second flex row (content) should have a height of the browser height minus the header height, the overflow of this container is set to scroll. The code works fine when the content container does not have to scroll, but as soon as the content container has any overflow the header row no longer contains its content. What could be causing this?

The Code:

<html>
<head>
    <style>
        .box {
            display: -ms-flexbox;  /* IE 10 */
            display: -webkit-flex; /* Safari 6 */
            display: flex;         /* Modern browsers */
            -ms-flex-direction: column;
            -webkit-flex-direction: column;
            flex-direction: column;
            flex-flow: column;
            height: 100%;
            width: 100%;
            border: 2px solid;
        }


        .box .row {
            flex: 0 1 30px;
            border: 2px solid;
            width: 100%;
        }

        .box .row.header {
            -ms-flex: 0 1 auto;
            -webkit-flex: 0 1 auto;
            flex: 0 1 auto;
        }

        .box .row.content {
            -ms-flex: 1 1 auto;
            -webkit-flex: 1 1 auto;
            flex: 1 1 auto;
            overflow: scroll;
        }

    </style>
</head>

<body>
    <div id="page-wrapper" style="height: 100%">
        <div class="box">
            <div class="row header">
                <p>Header - The height of the header is based on the content</p>
                <p>Header - The height of the header is based on the content</p>
            </div> <!-- end of flex row header -->
            <div class="row content">
                <p>When the content box is full, the header row does not contain change its length to contain its content properly</p>
            </div> <!-- end of flex row content -->
        </div> <!-- end of flex box -->
    </div> <!-- end of page wrapper -->
</body>
</html>

Rendered properly with content box having no overflow:

enter image description here

Rendered incorrectly with content box having overflow:

enter image description here

ptim
  • 14,902
  • 10
  • 83
  • 103
Alex Wetton
  • 199
  • 1
  • 1
  • 10
  • As I recall, Safari has problems with height values as percentages when dealing with children of `display: flex` elements. If the parent is a percentage then having children w/out declared heights might cause them to inherit that same percentage value. – TylerH Oct 01 '15 at 19:11
  • So If I want the parent (box) to always fill the whole page height, how should I go about setting it without using a percentage? – Alex Wetton Oct 01 '15 at 20:07
  • I can't test on Safari as I'm on a Windows machine, but you can try `100vh` to make the element equal the height of the viewport (the screen). – TylerH Oct 01 '15 at 20:56
  • I tried 100vh and 100vw and that did not solve the problem. – Alex Wetton Oct 01 '15 at 21:13
  • Not sure exactly what's causing your problem, but I know that if you're going to use percentage heights, you need to specify the height for parent and ancestor elements, up to and including the root element (`html`). That may not resolve this particular issue, but it might save you some headaches in the future. Start with this `html, body { height: 100%; }`. See my answer here for more details: http://stackoverflow.com/a/31728799/3597276 – Michael Benjamin Oct 01 '15 at 21:27
  • Oh, and I can't help because, like @TylerH, I'm on a Windows machine here. Otherwise I would try. Good luck. – Michael Benjamin Oct 01 '15 at 21:29
  • 1
    In this case it was not the use of percentages for heights that caused the problem, as the answer below still worked with percentage heights. – Alex Wetton Oct 02 '15 at 06:27
  • @Michael_B not related to the question, but it's usually better to leave the height as auto and use `html, body { min-height: 100% }`. If you set the body height to 100% then the body won't extend the full height of the document when it scrolls. See an example here: https://jsfiddle.net/tqv29ckb/ (uncomment the CSS to see how it fixes the layout) – ratherblue Oct 02 '15 at 18:47
  • @sev, Yeah, I've tried this before, except it doesn't necessarily work. The [spec](http://www.w3.org/TR/CSS21/visudet.html#the-height-property) clearly states that the `height` must be defined when dealing with percentages. It doesn't say `min-height`, and this makes a difference. What I've done, however, to make it work is use both `height` and `min-height` in a single rule. The first covers the W3C standard, the second deals with your point (and [`min-height` overrides `height`](https://developer.mozilla.org/en-US/docs/Web/CSS/min-height) anyway). Thanks for the feedback. – Michael Benjamin Oct 02 '15 at 18:57

2 Answers2

19

The reason the header isn't expanding is because you've specified flex-shrink: 1 on .box .row.header

By saying that the content is allowed to shrink you are letting the header get squished by the content area below it.

Change this:

.box .row.header {
  -ms-flex: 0 1 auto;
  -webkit-flex: 0 1 auto;
  flex: 0 1 auto;
}

To this:

.box .row.header {
  -ms-flex: 0 0 auto;
  -webkit-flex: 0 0 auto;
  flex: 0 0 auto;
}

And your page will now work in Safari.

ratherblue
  • 2,108
  • 11
  • 14
  • 1
    nice :) this is a (solution for) the classic case of FlexBug #1! https://github.com/philipwalton/flexbugs#1-minimum-content-sizing-of-flex-items-not-honored – ptim Jul 18 '16 at 02:22
1

This was a bug in older versions of Safari and how they handle flexbox. In the newest version 10.0.1, this is fixed.