1

How can we have an <img> or <canvas> that stretches/shrinks to fill the remaining space in a display: flex type of layout? It is straightforward to make a <div> fill the remaining space, but an <img> has its own idea of size that stops layout working properly. For example, suppose we have:

  • a parent <div> with display: flex,
  • a child <h1> with flex: 0 0 auto, and
  • a child <img> with flex: 1 1 0px.

As the window is resized, the <img> (or <canvas>) sometimes fits exactly but sometimes overflows the parent depending on the size or aspect ratio of the window.

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Simple Test</title>
        <style>
            body {
                width: 100vw;
                height: 100vh;
                box-sizing: border-box;
                display: flex;
                flex-flow: column nowrap;
                margin: 0px;
                border: 4px dashed lightcoral;
            }
            h1 {
                flex: 0 0 auto;
                margin: 0px;
                border: 4px solid chocolate;
            }
            div {
                flex: 1 1 0px;
                border: 4px dotted darkorchid;
            }
            canvas {
                width: 100%;
                height: 100%;
                box-sizing: border-box;
                border: 4px solid lightseagreen;
            }
        </style>
    </head>
    <body>
    <h1>Heading</h1>
    <div><canvas width="400" height="200"/></div>
    <script>
        var c = document.getElementsByTagName('canvas').item(0);
        var x = c.getContext('2d');
        x.ellipse(100, 100, 50, 50, 0, 0, 360);
        x.fill();
    </script>
    </body>
    </html>
user2357
  • 452
  • 5
  • 11
  • If this question should be deleted, that's fine, but I'm going to leave it because others might stumble onto it thinking the issue is specifically related to images or canvases. – user2357 Nov 11 '18 at 14:17

1 Answers1

4

Answering my own question, this is related to the behavior of flex-shrink, which is explained well by this question.

In short, flex items have a default min-width: auto which usually means the content width (or height depending on the flex-direction). Simply set min-width: 0 to allow the <img> or <canvas> to resize properly. This is perhaps more confusing in this case because it seems inappropriate to give these elements a minimum size.

user2357
  • 452
  • 5
  • 11