Maintain Aspect Ratio of Div But Fill Screen Width and Height in Css

Maintain aspect ratio of div but fill screen width and height in CSS?

There is now a new CSS property specified to address this: object-fit.

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

The feature is widely supported by now (http://caniuse.com/#feat=object-fit).

Maintain aspect ratio according to width and height

The aspect-ratio property (2022)

To maintain the aspect ratio of a div according to width and height, you can use the aspect-ratio property (MDN reference).

This allows you to maintain any aspect ratio according to the viewport size or to the size of the parent element.

Maintaining aspect-ratio according to the viewport size (width and height) :

.ar-1-1 {
aspect-ratio: 1 / 1;
background: orange;
}

.ar-1-19 {
aspect-ratio: 16 / 9;
background: pink;
}

div {
max-width: 100vw;
max-height: 100vh;
margin-bottom: 5vh;
}


/** For the demo **/

body {
margin: 0;
}
<div class="ar-1-1">Aspect ratio 1:1</div>
<div class="ar-1-19">Aspect ratio 1:19</div>

Maintain the aspect ratio of a div with CSS

Just create a wrapper <div> with a percentage value for padding-bottom, like this:

.demoWrapper {
padding: 10px;
background: white;
box-sizing: border-box;
resize: horizontal;
border: 1px dashed;
overflow: auto;
max-width: 100%;
height: calc(100vh - 16px);
}

div {
width: 100%;
padding-bottom: 75%;
background: gold; /** <-- For the demo **/
}
<div class="demoWrapper">
<div></div>
</div>

CSS force image resize and keep aspect ratio

img {  display: block;  max-width:230px;  max-height:95px;  width: auto;  height: auto;}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p><img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

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>

Keep aspect ratio of div. while using max-width

You could apply the padding-bottom to its ::before pseudoelement, e.g.

.some-class {
width: 100%;
max-width: 520px;
border: 1px #9bc solid;
}
.some-class::before {
padding-bottom: 100%;
content: "";
display: inline-block;
vertical-align: top;
}

demo

Doing so the padding is always computed relatively to the actual width of the div and not to the width of its ancestor (e.g. the body element)


Update (05/2021)

On recent browsers you could start using the new aspect-ratio property, so if the browser supports it you could simply write

.some-class {
width: 100%;
max-width: 520px;
border: 1px #9bc solid;
aspect-ratio: 1;
}

Maintain div aspect ratio according to height

You can use an image that has the desired proportions as to help with proportional sizing (images can be scaled proportionally by setting one dimension to some value and other to auto). The image does not have to be visible, but it must occupy space.

.box {  position: absolute;  bottom: 0;  left: 0;  height: 50%;}.size-helper {  display: block;  width: auto;  height: 100%;}.inner {  position: absolute;  top: 0;  bottom: 0;  left: 0;  right: 0;  background: rgba(255, 255, 153, .8);}
<div class="box">  <img class="size-helper" src="//dummyimage.com/200x100/999/000" width="200" height="100">  <div class="inner">    1. box has fluid height<br>    2. img has 2:1 aspect ratio, 100% height, auto width, static position<br>    2.1 it thus maintains width = 200% of height<br>    2.2 it defines the dimensions of the box<br>    3. inner expands as much as box  </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!

Scale div to fill screen while maintaining aspect ratio

I don't think this can be done with CSS only currently, as you would need to be able to read the width of certain elements, this cannot be done at the moment. But since JS is OK with you now, you could do something like this using jQuery:

function zoomit() {
$("#page1").css('zoom', $(window).width() / $("#page1").width());
}

$(document).ready(zoomit);

$(window).resize(zoomit);

Here's a jsFiddle

Here's a jsFiddle of the latest version which doesn't use zoom but -transform vendor tags only.

Edit:

I just realised that zoom doesn't actually work on Firefox. Instead you could use -moz-transform: scale(x, y); for Firefox and set x and y to the appropriate values, which you can work out in the same way as I have already done in the example above.

Edit2

Here's a link to w3schools with some info about CSS 2D transforms and the prefixes for other browsers, as you mentioned in the comments, writing something that checks if for width > height and the other way around, and then basing the transform on that, should do the trick for all browsers. Post the jsFiddle if you get it working and I'll add it to the answer, I'm happy to have a go at it if you don't get it working.

Keep div's aspect ratio and fill it to window with CSS only

For portrait screens, use a width of 100vw (the width of the window) and a height of 75vw (75% of the width of the window). For landscape screens, base the shape of the div on the height rather than the width.