I've got a div
element that maintains an aspect ratio: it calculates its height based on its width (using the padding trick). What I'd like to do is to put this div
into another one by fitting the maximum space available, vertically and horizontally, no crop. I think the closest thing to what I want is the object-fit: contain
- which is img
only.
I want the div to cover the max height and width possible while maintaining the aspect ratio. No vertical or horizontal crop.
Is it even possible with CSS only? If so, how?
Update: A good article where things are at the moment.
code (Can be any other solution, doesn't have to be built on this snippet):
html,
body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.container {
position: relative;
width: 100%;
}
.container:before {
content: "";
display: block;
width: 50%;
padding-top: 50%;
}
.embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: red;
}
<div class="container">
<div class="embed">
this should accommodate all the available space and maintain aspect ratio, no crop when width is too wide
</div>
</div>
In the HTML, put the player <iframe> in a <div> container. In the CSS for the <div>, add a percentage value for padding-bottom and set the position to relative, this will maintain the aspect ratio of the container. The value of the padding determines the aspect ratio. ie 56.25% = 16:9.
Method 1: First method is to simply assign 100% width and 100% height to the child div so that it will take all available space of the parent div. Consider this HTML for demonstration: HTML.
In order to maintain the aspect ratio of a div with CSS create flexible elements that keep their aspect ratio (4:3, 16:9, etc.) when resize the browser window. What is aspect ratio? The aspect ratio of an element describes the proportional relationship between its width and height.
2022 solution - use the aspect-ratio CSS property. Note: When you only use the width property with 100% as value, this width will be calculated, so that it won't fill the horizontal space. When you want to preserve the 100% width, you have to add both width and height with each 100% set.
The only workaround I managed to achieve so far is to wrap the child element in to svg's foraignObject tag:
const container = document.getElementById('container');
document.getElementById('btn').addEventListener('click', () => {
container.style.height = container.style.height === '100px' ? '200px' : '100px';
});
body {
margin: 1rem;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
button {
margin-bottom: 1rem;
}
#container {
background-color: #ffceaf;
width: 400px;
}
svg {
background-color: #b8d6ff;
height: auto;
width: auto;
max-width: 100%;
max-height: 100%;
overflow: hidden;
}
#content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: solid;
}
<button id="btn">Change parent height</button>
<div id="container" style="height: 100px;">
<svg width="15000" height="5000">
<foreignObject width="100%" height="100%">
<div id="content">
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
content content content content content content content
</div>
</foreignObject>
</svg>
</div>
This solution has downsides:
I feel like using JS might be better option here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With