Is there something like `object-fit: contain` for non-replaced elements?

Hello Kevil Powell community! I'm a bit of a noob with HTML and CSS, but I'd really like to learn. Recently, I've been trying to create a centered div with an aspect ratio of 3 / 7 that fills its parent the best can, acting something like object-fit: contain. Unfortunately, object-fit: contain doesn't seem to work for non-replaced elements. Here's a visualization of what I want to achieve in Flutter, which is something I have slightly more experience in. https://dartpad.dev/?id=eec1210050a099df1c5422fa66e891e5 It's fairly straightforward to create a div with an aspect-ratio with a fixed width or height, but I can't seem to make it work once it becomes responsive. I'd appreciate any help! Thanks!
DartPad
An online Dart editor with support for console and Flutter apps.
31 Replies
Chooβ™šπ•‚π•šπ•Ÿπ•˜
Flutter is not HTML or CSS. There is a way to make web apps using Flutter, but that is not by writing HTML or CSS.
eliaxelang007
eliaxelang007OPβ€’4d ago
Thanks for responding! Yup, I get that Flutter is not HTML or CSS. I just included an example of what I wanted to achieve in Flutter because I don't know how to do the same thing using HTML and CSS.
13eck
13eckβ€’4d ago
eliaxelang007
eliaxelang007OPβ€’4d ago
Woah! How does this work?
13eck
13eckβ€’4d ago
Just needed some flexbox and it works!
13eck
13eckβ€’4d ago
Normally, block level elements (headers, divs, paragraphs, etc) take up only as much vertical space as they need. So I first needed to set the parent container to fill the entire viewport height (but by default they take up full width, so that was taken care of already). From there, I set the properties on the actual element I wanted to be centered. Aspect ratio, of course, set the size ration. the two margin- properties told the browser what to do with the "leftover" space, so it was added in equal measure to all sides of the element, centering it. And the max-*-size constrained the size to actually use the aspect ratio. Lastly, I made the parent element a flex container so the bule element could center both horizontal and vertical.
eliaxelang007
eliaxelang007OPβ€’4d ago
Thanks so much for the explanation! I opened your codepen (https://codepen.io/c__beck/pen/bNbMZzY) on my machine, but it doesn't seem to work quite the same way. Am I doing something wrong?
13eck
13eckβ€’4d ago
You opened it in Firefox, when I created it in Chrome. Apparently firefox doesn't support something that makes it work
eliaxelang007
eliaxelang007OPβ€’4d ago
Same machine but on Chrome now, and it still doesn't work. Maybe it's something wrong with how I set up my codepen?
13eck
13eckβ€’4d ago
You opened the link, right? Not made a new pen? It should work, then
eliaxelang007
eliaxelang007OPβ€’4d ago
If so then yeah
13eck
13eckβ€’4d ago
Weirdly, if you remove the display: flex; from the container CSS it'll work, but be "pinned" to the top. IE the top margin won't work
eliaxelang007
eliaxelang007OPβ€’4d ago
I opened this link Ohhhh Ok let me try that
13eck
13eckβ€’4d ago
Not sure why you're not getting the same results as I am on Chrome
eliaxelang007
eliaxelang007OPβ€’4d ago
Yeah, removing display flex worked! Is there a different way I can center it vertically?
13eck
13eckβ€’4d ago
Ok, refresh the pen. I think I fixed it The aspect ratio was interacting weirdly with setting both a max inline size and max block size, so I removed the block size and re-did the calculation for the inline size
eliaxelang007
eliaxelang007OPβ€’4d ago
Yup! This works the same way on my machine now. Thank you so much!
13eck
13eckβ€’4d ago
πŸ‘
eliaxelang007
eliaxelang007OPβ€’4d ago
If you're willing, could I please ask one more question? Is it possible to adapt the max-inline-size: calc((3 / 7) * 100vh); to work for the height of any container and not just the height of the viewport? I changed max-inline-size with something I'm more familiar with, max-width, for my convenience. I've been wanting to do something like max-width: calc((3 / 7) * 100%); where 100% is of the height and not the width, but CSS doesn't seem to have that functionality?
13eck
13eckβ€’4d ago
inline is just a logical property. For RTL, TTB languages like English it's the same as width so yeah, that's fine. As for the calc function, I made a few adjustments to the pen. have a look
eliaxelang007
eliaxelang007OPβ€’4d ago
It still doesn't work :/
eliaxelang007
eliaxelang007OPβ€’4d ago
I've been playing with it on my own as a fork of just_13eck's, trying to remove the dependency on the vw units, but the things I try don't seem to work. https://codepen.io/Eli-Ang/pen/dPbeLMp?editors=1100
eliaxelang007
eliaxelang007OPβ€’4d ago
In my codepen, when the flex-direction is column the element is only responsive to height changes, and when flex-direction is row, the element is only responsive to width changes. Is something like the Flutter example not possible for containers with widths and heights that aren't viewport sized?
13eck
13eckβ€’4d ago
You're not going to be able to remove the viewport unit dependancies. By default, block-level elements take up only as much vertical room as the content requires. In this case, there is no content so the elements shrink to literally nothingness. If you want there to be content-less height you use vh. Or even if you want there to be contentful height, you use vh to set that initial full-height containing block.
eliaxelang007
eliaxelang007OPβ€’4d ago
Ok, so am I better off trying to use javascript to manipulate the widths and heights to get the result I want?
13eck
13eckβ€’4d ago
No, use CSS. Adding JS for convienence is bad practice. Why don't you want to use viewport units to set the height of the parent container?
eliaxelang007
eliaxelang007OPβ€’4d ago
Well, I want to put the div with the class .container inside an already established layout
13eck
13eckβ€’4d ago
Then set the height on the existing layout container
eliaxelang007
eliaxelang007OPβ€’4d ago
Ok, I think that will work. I'll get back to you in a bit to test a bit Ok, I think it works well enough now. Thank you!
eliaxelang007
eliaxelang007OPβ€’3d ago
I just discovered something! For anybody who still needs to remove the dependency on viewport units, you can use container queries! https://codepen.io/Eli-Ang/pen/dPbeLMp
<div class="game-container">
<div class="game-area">
<div class="game">
</div>
</div>
</div>
<div class="game-container">
<div class="game-area">
<div class="game">
</div>
</div>
</div>
* {
margin: 0;
}

html,
body {
width: 100%;
height: 100%;
}

.game-container {
width: 100%;
height: 100%;
container: game-containment / size;
}

.game-area {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}

@container game-containment (aspect-ratio < 3 / 7) {
.game-area {
flex-direction: row;
}
}

.game {
background-color: royalblue;
aspect-ratio: 3 / 7;
flex-grow: 1;
}
* {
margin: 0;
}

html,
body {
width: 100%;
height: 100%;
}

.game-container {
width: 100%;
height: 100%;
container: game-containment / size;
}

.game-area {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}

@container game-containment (aspect-ratio < 3 / 7) {
.game-area {
flex-direction: row;
}
}

.game {
background-color: royalblue;
aspect-ratio: 3 / 7;
flex-grow: 1;
}

Did you find this page helpful?