Search code examples
htmlcssipadsafariflexbox

IPad, Safari, CSS: Fill page with flex


I try to make a layout with flex which expands the main area to the whole display height. When the content is small a footer is always on the bottom. When the main content is higher than the display size it should behave like a normal page and scroll until the footer.

The following code work like expected on my workstation with Firefox and Chrome but on my IPad with Safari the footer is set anywhere in the page. The problems comes when setting the html height to 100%. Without setting any height to the html part it works, but when the main content is smaller than the display height the body isn't stretched.

IMPORTANT: This can't be reproduced with JSFiddle because they use an IFrame and but the whole HTML inside.

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
    html {
        height: 100%;
        margin: 0;
    }
    body {
        margin: 0;
        display: flex;
        flex-direction: column;
        height: 100%;
    }
    main {
        flex-grow: 1;
    }
    div {
        background-color: yellow;
        height: 1200px;
    }
    </style>
</head>
<body>
    <main>
        <div>main</div>
    </main>
    <footer>
        footer
    </footer>
</body>
</html>

UPDATE: The problem can also be reproduced under Mac OS X with Safari 9.0.2


Solution

  • I finally solved the problem. It's important to add height: auto; and min-height: 100%; to body and html and position: absolute; to body.

    Here is the final code which worked on all my test environments.

    <!DOCTYPE html>
    <html>
    <head>
    <style type="text/css">
    html {
        height: auto;
        min-height: 100%;
        margin: 0;
    }
    
    body {
        margin: 0;
        display: flex;
        flex-direction: column;
        height: auto;
        min-height: 100%;
        position: absolute;
        width: 100%;
    }
    
    main {
        flex-grow: 1;
    }
    
    div {
        background-color: yellow;
        height: 200px;
    }
    </style>
    </head>
    <body>
        <main>
            <div>main</div>
        </main>
        <footer> footer </footer>
    </body>
    </html>