Search code examples
htmlcssgrid-layoutaspect-ratio

Preserving aspect ratio in a CSS grid


I'm trying to implement responsive grid containing 3x4 elements. I'm also using a bitmap image for each cell so I would like to preserve the aspect ratio of each cell. The problem I'm having now, is that my CSS doesn't prevent it from overflowing the vertical size of the viewport. It works fine when scaling on the horizontal axis.

Works as expected: Works as expected

Doesn't work as expected (creates a scrollbar): Doesn't work as expected

Link to CodePen: http://codepen.io/ekulabuhov/pen/JEyxby?editors=1100

.container{
  height:100vm; width:100vm; /* IE9 fallback */
  width: 100vmin; height: 100vmin;
  position: absolute;
  top:0;bottom:0;
  left:0;right:0;
  margin: auto;
}

.gametile {
  background: url('http://adrianpayne.me/game/assets/images/grass.png') no-repeat; 
  background-size: cover;

  /* 33.3vmin; */
  width: calc(100vmin/3);
  float:left;
  height: calc(100vmin/3*(91/70));
  margin-top: -16vmin;
}


/*** FOR THE DEMO **/
body,html {margin:0;background:#123752;color:#fff;}
a{color:#ccc;}
<div class="container">
  <div class="gametile"></div>
  <div class="gametile"></div>
  <div class="gametile"></div>
  
  <div class="gametile"></div>
  <div class="gametile"></div>
  <div class="gametile"></div>
  
  <div class="gametile"></div>
  <div class="gametile"></div>
  <div class="gametile"></div>

  <div class="gametile"></div>
  <div class="gametile"></div>
  <div class="gametile"></div>
</div>


Solution

  • .container{
      height:100vm; width:100vm; /* IE9 fallback */
      width: calc(((100vmin - 16vmin) / 4 + 16vmin) * (70 / 91) * 3);
      height: 100vmin;
      position: absolute;
      top:0;bottom:0;
      left:0;right:0;
      margin: auto;
    }
    
    .gametile {
      background: url('http://adrianpayne.me/game/assets/images/grass.png') no-repeat; 
      background-size: cover;
    
      /* 33.3vmin; */
      width: calc(100% / 3);
      float:left;
      height: calc((100% - 16%) / 4 + 16%);
      margin-bottom: -16vmin;
    }
    
    
    /*** FOR THE DEMO **/
    body,html {margin:0;background:#123752;color:#fff;}
    a{color:#ccc;}
    <div class="container">
      <div class="gametile"></div>
      <div class="gametile"></div>
      <div class="gametile"></div>
      
      <div class="gametile"></div>
      <div class="gametile"></div>
      <div class="gametile"></div>
      
      <div class="gametile"></div>
      <div class="gametile"></div>
      <div class="gametile"></div>
    
      <div class="gametile"></div>
      <div class="gametile"></div>
      <div class="gametile"></div>
    </div>

    Don't know if it works in IE9, but I fixed it for you. It probably won't work in IE anything. You can also try display: grid if you give up on older browsers.