I have for months been going round in circles with this so the time has come to ask for help. I suspect that Paul OB will nail it straight away and explain it to me in words of one syllable that I will understand.
I have a very simple page, with an h1 at the top then an image and eblow that a nav div. I want the whole page to fill the height of the viewport. I want the image to have it’s aspect ratio preserved and in order to fit I want it’s height to be such that along with the h1 and nav it just fills the height of the viewport. It took me a while to be able to write out in English what I wanted.
I think this codepen shows where I have got to.
I tried many many many different things, going away from it and returning later, for 2-3 months!
I have tried to avoid “magic numbers”.
I have tried creating a new div and making the image the background but this wouold only display the image if I had some text in the div.
I must be missing something simple but fundmental. Any help, pointers/guidance gratefully received.
OP here again - I am aware that my HTML is invalid as I haven’t specified a width and height in the img tag and would be grateful for what I should do re this. Thank you.
but now we’re back where we started. Let’s use that flexing we’ve got…
div {
flex: 1
}
Now my div’s the right size. But the picture isn’t filling the div. Object-fit is great, but it is usually about fitting big things in small boxes, not the other way around.
This is where Paul will definitely do things better than me, but I found this works up until the point that the window gets so small that the image forces the main container to break (IE: 400px wide)
I’m not at a computer today so can’t offer code but there are a few logic errors in your code.
First of all get rid of the flex on the body as that just confuses things.
Set a page wrapper (you have main as a page wrapper but that’s not semantically correct). I would use a whole page container and set it to min-height:100vh (no need for magic numbers using calc and do not use height). Set it to flex and column direction.
Then have a header, a main element and a footer element. (3 separate elements)
Then just set main to flex :1 0 0 and that will make main fill all the space available apart from the header and footer.
You could then just put the image as a background to main and use background size cover. You can’t use contain as that will not always fill the height.
You could use an image in the html instead but once again you would need cover and a width and height of 100%.
If you need the whole of the image to show without being cropped as cover would do then you’d need contain but that means it will not fit width and height at the same time as the viewport is not the same aspect ratio as an image. That’s not a limitation of. CSS but just obeying the laws of the universe
I’ll put up a demo when I get home tonight if the above doesn’t make sense.
Excellent reply, as ever - thank you. I think I understand it all - very clearly explained. I will have a go at that but I may not be able to until tomorrow. Thank you so much.
I think you more or less said the same as me apart from a small detail.
If you set the image to height:100% then the width must be set to auto or the aspect ratio is lost. This may indeed mean the image is miles too wide for the viewport if it is a landscape type image. A max width would break the aspect ratio when it comes into effect. If all the images are portrait size then it should be ok at most sizes.
There is no solution other than using contain or cover to crop or restrain dimensions.
I realised that this page will be one of several linking from one to the other, each with a different picture. So I will need to use the img tag in html. I have tried doing this following your advice Paul but I get scroll bars when the viewport height gets below a certain size.
I think the answer lies in your reply somewhere but I can’t quite get it right. I don’t want the image to be cropped. I want the aspect ratio to be maintained. But as the viewport height shrinks I want the image height to be shrunk. I realise, of course, as you point out that the image width will then no longer fill the viewport width - I accept that that is physics/geometry.