16

It is possible to fit and center a square div in the viewport and always maintain it's aspect ratio according to width and height?

Requirements :

  • only CSS
  • the size of the square must adapt to the smallest dimension (width or height) of viewport regardless of the orientation (landscape or portrait) of the viewport.
  • the square must be centered horizontaly and verticaly in the viewport

Example:

Maintain aspect ratio according to width and height of viewport

web-tiki
  • 92,319
  • 29
  • 210
  • 241
TheGr8_Nik
  • 2,912
  • 1
  • 16
  • 31
  • 1
    check this [fiddle](http://jsfiddle.net/P8cA8/).. I am not sure about the vertical though.. – Mr_Green May 13 '14 at 11:43
  • the outer div should be the window and the inner square should fit it, but when it is higher than wider it doesn't work – TheGr8_Nik May 13 '14 at 11:46

4 Answers4

24

To maintain the aspect ratio of a div according to width and height in the viewport, you can use one HTML tag with:

  1. vmin units for the sizing :

    vmin 1/100th of the minimum value between the height and the width of the viewport.
    (source : MDN)

  2. position: absolute and margin: 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>
Flimzy
  • 68,325
  • 15
  • 126
  • 165
web-tiki
  • 92,319
  • 29
  • 210
  • 241
  • 1
    Regarding your ie10 caution: caniuse says: Partial support in IE9 refers to supporting "vm" instead of "vmin" - so that's not applicable here because we're not using vmin – Danield May 13 '14 at 12:38
  • 2
    Setting the body margin to 0 is also critical – sooks May 12 '15 at 09:38
5

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>
easwee
  • 15,262
  • 24
  • 58
  • 82
2

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;
    }
}
Rupert Rawnsley
  • 2,513
  • 1
  • 25
  • 38
  • This has got to be one of the most underappreciated answers I've seen on SO. It took me hours to finally find a working solution for non-square aspect ratios. Thank you very much, sir. – natiiix Jul 22 '18 at 16:30
-1

Use something like this

.container{
    display:block;
    background:#f2f2f2;
}

.square{
    width:50%;
    padding-top:50%;
    margin: auto;
    background:#e5e5e5;
}

DEMO

demonofthemist
  • 3,853
  • 3
  • 23
  • 41