I have a problem to solve that sounds simple. Let’s say I got a layout of a header, content and footer. Then I have a row of items in the content, filling all the space. Each item in the content section is equal in width and each has one child.
The children need to feel their parents perfectly, taking as much space as they can, but never scaling up. In other words, something that object-fit: scale-down
would do if these were images.
Let’s say the sizes of the elements I need to fit in there are:
200 x 300
1920 x 1080
1080 x 1920
This is the result I’m looking for:
I’m struggling to make it work correctly, bigger elements always either overflowing the container or getting clipped.
html,
body {
background-color: #000;
height: 100%;
margin: 0;
padding: 0;
}
.layout {
display: flex;
flex-direction: column;
height: 100%;
}
.top,
.bottom {
background-color: #444;
flex-shrink: 0;
height: 50px;
}
.middle {
background-color: #222;
flex-grow: 1;
overflow: hidden;
}
.items {
display: flex;
gap: 20px;
height: 100%;
overflow: hidden;
}
.item {
align-items: center;
background-color: #666;
display: flex;
flex-grow: 1;
justify-content: center;
overflow: hidden;
}
.block {
background-color: #f80;
background-image: linear-gradient(45deg, orange, purple);
height: 100%;
width: 100%;
}
.block1 {
max-height: 200px;
max-width: 300px;
}
.block2 {
max-height: 1080px;
max-width: 1920px;
}
.block3 {
max-height: 1920px;
max-width: 1080px;
}
<div class="layout">
<div class="top"></div>
<div class="middle">
<div class="items">
<div class="item">
<div class="block block1"></div>
</div>
<div class="item">
<div class="block block2"></div>
</div>
<div class="item">
<div class="block block3"></div>
</div>
</div>
</div>
<div class="bottom"></div>
</div>
So to sum up, I got rectangles of certain size that can be scaled down, not up, and obviously can’t change the aspect ratio. By the way, I tried to experiment with aspect-ratio
too, without success.
Can it be done without JavaScript calculations?
2
Answers
It does seem to be achievable with
aspect-ratio
property and@container
queries:height: 100%; width: 100%;
from.block
to allowauto
width and height.max-height
, keepmax-width
, addwidth: 100%
.aspect-ratio
containingwidth / height
values without pixels (aspect-ratio: 300 / 200;
for.block1
);@container
query to flip the sizing when there is not enough space. For.block1
:max-width
, keepmax-height
, addheight: 100%
.aspect-ratio
similarly as to "horizontal" –width / height
(aspect-ratio: 1080 / 1920;
for.block3
);@container
query to flip the sizing when there is not enough space. For.block3
:container-type: size;
to.item
so it’s declared as a size query container.Snippet:
This can be achieved without
@container
requests. You say you know the dimensions… That way you can give them to the<canvas>
element and it will be sized according to self aspect ratio.Here is an example based on your code: