Maintain aspect ratio according to width and height
You can achieve a responsive square using the vw & vh units (viewport-percentage lengths) to size it.
Check for browser support: http://caniuse.com/viewport-units
Solution that implements both horizontal and vertical scaling
Live sample page: http://sample.easwee.net/responsive-square/
.container {
display:table;
width:100%;
height:100%;
}
.container-row {
display:table-row;
}
.container-cell {
display:table-cell;
vertical-align:middle;
text-align:center;
}
.square {
display:inline-block;
background:red;
border: 3px solid blue;
}
@media(orientation:landscape) {
.square {
width: 100vh;
height: 100vh;
}
}
@media(orientation:portrait) {
.square{
width: 100vw;
height: 100vw;
}
}
<div class="container">
<div class="container-row">
<div class="container-cell">
<div class="square"></div>
</div>
</div>
</div>
I've combined the excellent answers from @ken-sharpe and @easwee to create a version for non-square aspect ratios: https://codepen.io/anon/pen/GyqopP
div {
position: absolute;
top:0;bottom:0;
left:0;right:0;
margin: auto;
width: 100vw;
height: 50vw;
background: #326384;
}
@media (min-aspect-ratio: 2/1) {
div {
width: 200vh;
height: 100vh;
background-color:green;
}
}
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>
Maintaining aspect ratyio according to the parent elements size (width and height) :
section {
width: 50%;
margin: 0 auto 5vh;
height:250px;
}
.ar-1-1 {
aspect-ratio: 1 / 1;
background: orange;
}
.ar-1-19 {
aspect-ratio: 16 / 9;
background: pink;
}
div {
max-width: 100%;
max-height: 100%;
}
/** For the demo **/
body {
margin: 0;
}
<section>
<div class="ar-1-1">Aspect ratio 1:1</div>
</section>
<section>
<div class="ar-1-19">Aspect ratio 1:19</div>
</section>
Previous answer with vmin units
This still works fine but it doesn't allow to maintain the aspect ratio according to a parent element size.
To maintain the aspect ratio of a div according to width and height in the viewport, you can use one HTML tag with:
- vmin units for the sizing :
vmin 1/100th of the minimum value between the height and the width of the viewport.
(source : MDN) position: absolute
andmargin: auto;
for the centering
DEMO (resize both window height and width to see it in action)
Features :
- keeps it's aspect ratio according to width and height
- stays centered in viewport horizontaly and verticaly
- never overflows the viewport
Browser support :
vmin
units are supported by IE10+ (canIuse) for IE9 support, you need to use a fallback with vm
units instead of vmin
like this :
width: 100vm; /* <-- for IE9 */
height: 100vm; /* <-- for IE9 */
width: 100vmin;
height: 100vmin;
Full code:
body {
margin:0; /* To prevent scrollbars */
}
div{
/* Aspect ratio */
height:100vm; width:100vm; /* IE9 fallback */
width: 100vmin;
height: 100vmin;
/*Centering */
position: absolute;
top:0;bottom:0;
left:0;right:0;
margin: auto;
/* styling */
background: gold;
}
<div>whatever content you wish</div>