Fill a Parent Div While Maintaining a Ratio

Fill a parent div while maintaining a ratio

Using aspect-ratio: 16 / 9; overflow: hidden; (aspect-ratio MDN docs) should give you the exact result you're looking for without needing to use the padding trick. Make sure the parent is set to display: grid or else it may not scale properly.

The aspect-ratio CSS property is supported by all major browsers (caniuse.com) except Safari, though Safari plans to add support this year. This is the best/correct way to achieve this effect, without having to resort to JavaScript or any hack solutions.

Related questions and answers here on Stack Overflow:

  • https://stackoverflow.com/a/66786774/3824249 (very similar to my solution)
  • https://stackoverflow.com/a/20593342/3824249 (another CSS-only alternative, though hackier using position: absolute for element positioning)

Here is my solution in action:

html, body { height: 100%; }

.parent {
display: grid;
resize: both;
height: 50%;
width: 90%;
border: 2px solid #000;
overflow: hidden;
}

.child {
width: 100%;
max-height: 100%;
margin: auto;
aspect-ratio: 16 / 9;
overflow: hidden;
box-sizing: border-box;
position: relative;
background: #a0522d;
text-align: center;
font-size: 20px;
color: white;
/* using the below to center the text, optional */
display: flex;
align-items: center;
justify-content: center;
}
<div style="padding: 5px 10px; margin-bottom: 10px; background: #f00; color: #fff; text-align: center; z-index: 1;">Resize the block below using the resize controls to see this in action.</div>
<div class="parent">
<div class="child">content that is not images...</div>
</div>

Div that fits into parent and maintains an aspect ratio

Ok, it looks like it can't be solved by CSS only. If anyone interested, I've put together a React component that does the job (Tests and better README soon, when I have time).

It wraps its children into a div and uses JavaScript to compute the width and height of that div in order to accommodate the available space while maintains the given aspect ratio. It basically stretches the wrapper until one of the sides reaches its maximum.

BREAKING UPDATE a CSS only solution has been found!

How to fill a div but maintain aspect ratio for child divs

You already have squared buttons.
The thing you miss is the width of those buttons but it's something you can calculate easily.

The div #menu has a height of 100vh - 7%, it means that your buttons should have a height of (100vh - 7%) / 5.

Their height ise equal to their width, so if they have width: calc(93vh / 5) they will fill the height of the #menu.

Therefore, you can simply add #menu { width: calc(93vh / 5)}

I would also remove #main { height: 100% }, it's not needed.

html, body {    margin:0;    padding:0;}#container {    display:flex;    flex-direction: column;    background-color: #444;    height:100vh;    width:100%;    margin:0;    padding:0;}#top{    background-color: #777;    height:5%;    width:100%;    margin:0;    padding:0;  }#main{    background-color: #DDD;    /* height:100%; not needed */    width:100%;     margin:0;    padding:0;    align-items: stretch;}#menu{    display:flex;    flex-direction: column;    background-color: #FFF;    height:100%;    width: calc((93vh) / 5); // Width of the menu = Height of the menu divided by the number of buttons    margin:0;    padding:0;  }.buttons{    display:block;    position:relative;    height:0;    margin:0;    padding-bottom:100%;}#button1{background-color:blue; margin:2px 0 2px 0;}#button2{background-color:green; margin:2px 0 2px 0;}#button3{background-color:red; margin:2px 0 2px 0;}#button4{background-color:black; margin:2px 0 2px 0;}#button5{background-color:orange; margin:2px 0 2px 0;}.img-container {  justify-content: center;  display: flex;  flex-direction: row;  overflow: hidden;  padding:16px;}.img-container .img-to-fit {  flex: 1;  height: 100%;}
.fill { display: flex; justify-content: center; align-items: center; overflow: hidden}.fill img { flex-shrink: 0; min-width: 100%; min-height: 100%}

#bottom { height:2%; display:flex;}#bottom1{background-color:blue;}#bottom2{background-color:green;}#bottom3{background-color:red;}#bottom4{background-color:white;}#bottom5{background-color:orange;}.bottoms{ height:100%; width:20%; margin:0; padding:0;}
<div id="container">    <div id="top">    </div>    <div id="main">        <div id="menu">            <div id="button1" class="buttons">                <div class="img-container">                  <img class="img-to-fit" src="parcel.png" />                </div>                      </div>            <div id="button2" class="buttons">
</div> <div id="button3" class="buttons">
</div> <div id="button4" class="buttons">
</div> <div id="button5" class="buttons">
</div> </div> </div> <div id="bottom"> <div id="bottom1" class="bottoms">
</div> <div id="bottom2" class="bottoms">
</div> <div id="bottom3" class="bottoms">
</div> <div id="bottom4" class="bottoms">
</div> <div id="bottom5" class="bottoms">
</div> </div></div>

Make square div fill parent at all time without losing its aspect ratio

Maybe something like this would help:
http://jsfiddle.net/2bg1jzg3/5/

$(".visual").animate({    width: "600px",    height: "300px"}, 2000, function () {    // Animation complete.});
.visual {    background-color:lightblue;    position:absolute;    overflow:hidden;    width:250px;    height:600px;}.parent {    width:auto;    height:100% !important;    position: relative;    display: block;}.parent .square-child {    position: absolute;    top: 0;    bottom: 0;    left: 0;    right: 0;    background-repeat:no-repeat;    background-size:cover;    background-position: center;    background-image: url('http://lorempixel.com/output/abstract-q-g-850-480-8.jpg');    width: 50%;    height: 0;    padding-bottom: 50%;    margin: auto;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="visual">    <div class="parent">        <div class="square-child"></div>    </div></div>

How to make div element auto-resize maintaining aspect ratio?

The aspect-ratio ref property has a good support now so you can use the below:

body {
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background: gray;
}

.stage {
--r: 960 / 540;

aspect-ratio: var(--r);
width:min(90%, min(960px, 90vh*(var(--r))));

display: flex;
justify-content: center;
align-items: center;


background:
/* this gradient is a proof that the ratio is maintained since the angle is fixed */
linear-gradient(30deg,red 50%,transparent 50%),
chocolate;
}
<div class="stage">
<p>Some text</p>
</div>


Related Topics



Leave a reply



Submit