htmlcsslayoutresponsive-designresponsive

how to have <img> shrink instead of ever having y-overflow occur when page is too short


this question might seem trivial but with 3 years of frontend development experience I am failing at this. I created a minimum reproducible example.

this is my code of the example. For viewing it, I suggest creating an html file and viewing the code in the browser with the iPhone SE screen size (375x667) since then the y-overflow becomes apparent.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Image and Div Layout</title>
        <style>
            body {
                margin: 0;
            }

            .container {
                max-height: 100vh;
            }

            .container img {
                max-width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="https://wallpapercave.com/dwp2x/wp4471355.jpg" alt="Image">
            <div>
                <p>1Your content here</p>
                <p>2Your content here</p>
                <p>3Your content here</p>
                <p>4Your content here</p>
                <p>5Your content here</p>
                <p>6Your content here</p>
                <p>7Your content here</p>
                <p>8Your content here</p>
                <p>9Your content here</p>
                <p>10Your content here</p>
                <p>11Your content here</p>
                <p>AAAAAAAAAAAAAAAAA</p>
            </div>
        </div>
    </body>
</html>

Im this image you can see that only number 8 is visisble anymore but not number 9,10,11…

enter image description here

I am testing on iPhone SE sizes in google chrome developer tools on my laptop.

I always want to be able to see all of the <p>'s, and never have any y-overflow. If there is not enough space well then the <img> element should shrink.

so the <p>AAAAAAAAAAAAAAAAA</p> element should be at the very bottom of the page. then upwards the remaining <p> elements and then finally the image should take up the remaining space.

the <img> should shrink as in its height & width should get smaller, in the correct ratio. keyword: object-fit: contain (but it did not work for me)

the image should also be centered horizontally & vertically inside its "remaining-space-container"

I would prefer a solution that does not use any viewport units if possible, Since in my real use case there is other elements on the page too with which this would conflict. So the solution should rely on the currently available height which in this example case is 100vh but in practice might not always be.

But if using viewport is really the only solution (which would be highly surprising) then it can be used too.

I tried doing things with height: 100vh and flexbox, flex-grow, grid but they did all not work.


Solution

  • Try this

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Image and Div Layout</title>
        <style>
            body {
                margin: 0;
            }
    
            .container {
                height: 100vh;
                display: flex;
                flex-direction: column;
                overflow-y: hidden;
            }
    
            .img-container {
                flex: 1 1 auto;
                height: 100%;
                background-color: #550000;
                display: flex;
                justify-content: center;
                overflow-y: hidden;
            }
    
            .img-container img {
                object-fit: contain;
                max-width: 100%;
            }
        </style>
    </head>
    
    <body>
        <div class="container">
            <div class="img-container">
                <img src="https://wallpapercave.com/dwp2x/wp4471355.jpg" alt="Image">
            </div>
    
            <div>
                <p>1Your content here</p>
                <p>2Your content here</p>
                <p>3Your content here</p>
                <p>4Your content here</p>
                <p>5Your content here</p>
                <p>6Your content here</p>
                <p>7Your content here</p>
                <p>8Your content here</p>
                <p>9Your content here</p>
                <p>10Your content here</p>
                <p>11Your content here</p>
                <p>AAAAAAAAAAAAAAAAA</p>
            </div>
        </div>
    </body>
    
    </html>