Reputation: 512
I have found this css code that allows me to keep a div's aspect ratio.
.container {
width: 100%;
height: 100%;
background-color: red;
position: absolute;
}
.wrapper {
width: 100%;
/* whatever width you want */
display: inline-block;
position: relative;
top: 50%;
transform: translate(0%, -50%);
}
.wrapper:after {
padding-top: 56.25%;
/* 16:9 ratio */
display: block;
content: '';
}
.main {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
/* fill parent */
background-color: deepskyblue;
/* let's see it! */
color: white;
}
See this JSFiddle example: https://jsfiddle.net/1uyo07tg/3/
I would like a css-only solution (without the use of VW or VH) to keep this aspect ratio even when the parent is wider than the aspect ratio in question (in this case, 16:9).
In other words, I would like the blue-colored div to stay at 16:9 ratio even when the parent (.container) is stretched wider than 16:9.
Clarifying - i would like some css-only solution, to have a child div stay always in a fixed ratio, centered vertically and horizontally, no matter the size or aspect ratio of the parent div, and without using vw,vh. I am pretty sure this needs JS code (which I have), but just wanted to see if someone has a css-only neat trick for it.
Bottom line - looking for this functionality in CSS only, no vh or vw.
Hope that makes sense. Any ideas?
Thanks in advance, Sa'ar
Upvotes: 7
Views: 2874
Reputation: 206102
position: absolute
with top,right,bottom,left
positions, or just the inset
rule to 0
margin: 0
to center itmax-width
and max-height
to 100%
for the contain magic/* QuickReset */ * { margin: 0; box-sizing: border-box; }
#parent {
/* This can be just any element with responsive W/H */
min-height: 100vh;
background-color: red;
position: relative;
}
#aspectRatio {
background-color: #0bf;
position: absolute;
inset: 0; /* or use: top:0; right:0; bottom:0; left:0;*/
margin: auto;
max-width: 100%;
max-height: 100%;
aspect-ratio: 16 / 9;
}
<div id="parent">
<div id="aspectRatio">Lorem</div>
</div>
Here's another example Fixed header and footers, aspect ratio body
Here I created a JS implementation if you're interested in the intricacies and calculation:
const contain = (EL, rx, ry) => {
// We need to rely on JS since Firefox is still experimental with aspect-ratio
// https://stackoverflow.com/a/66721382/383904
const scale = 1.0; // 1 = max parent size. 0.8 = scale down
const margin = 0; // PX gutter around the box
rx *= scale;
ry *= scale;
const parent = EL.parentElement;
const pw = parent.offsetWidth * scale - margin;
const ph = parent.offsetHeight * scale - margin;
// If H should apply instead of W and vice versa
const isSwap = pw / ph > rx / ry;
const w = isSwap ? (ph / ry) * rx : pw;
const h = isSwap ? ph : (pw / rx) * ry;
EL.style.cssText = `width: ${w}px; height: ${h}px;`;
};
const ELS_aspectRatio = document.querySelectorAll(".ar-box");
const applyContain = () => ELS_aspectRatio.forEach(EL => contain(EL, 16, 9));
window.addEventListener("resize", applyContain);
applyContain();
* { margin: 0; box-sizing: border-box; }
/* DEMO ONLY: This can be any responsive parent with any responsive unit! */
#parent {
width: 100vw;
height: 100vh;
background-color: red;
display: flex;
justify-content: center;
align-items: center;
}
.ar-box {
background-color: #0bf;
}
<div id="parent">
<div class="ar-box">Contain using JS</div>
</div>
Upvotes: 17
Reputation: 394
body,html {
margin: 0;
height: 100%;
width: 100%;
}
.container {
width: 100%;
height: 100%;
background-color: red;
overflow: hidden;
}
.wrapper {
width: 100%;
max-width: calc(100vh / 0.5625);
padding-top: 56.25%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: deepskyblue;
}
.main
is even not nessary
Upvotes: -1