Search code examples
htmlcsscss-grid

Equal height different aspect ratio boxes with CSS grid


I'm trying to create layout like this:

enter image description here

  • Orange blocks on the right side all have the same aspect ratio and thus height.
  • Blue block has different aspect ratio.
  • Height of blue block and summ of orange blocks should be equal, as shown on the image.

Is there a way to create such layout via CSS grid? I know that I can wrap orange items in a separate column element, but I'd like to avoid this. I also managed to create this layout when aspect ratio of each item is square, but no luck with this one...

Example on jsfiddle http://jsfiddle.net/fq974gov/

 .grid {
  display: grid;
  grid-gap: 10px;
  width: 200px;
}
.item-left {
  background: lightblue;
  padding-bottom: 120%;
}
.item-right {
  background: tomato;
  padding-bottom: 60%;
}
<div class="grid">
  <div class="item-left"></div>
  <div class="item-right"></div>
  <div class="item-right"></div>
  <div class="item-right"></div>
</div>


Solution

  • You can define template areas and control the ratio using grid-template-columns

    .grid {
      display: grid;
      grid-template-areas:
        "l1 r1"
        "l1 r2"
        "l1 r3";
      grid-template-columns:3fr 2fr; /*adjust this as you like*/
      grid-gap: 10px;
      width: 200px;
      animation:change 2s infinite alternate linear;
    }
    .item-left {
      grid-area:l1;
      background: lightblue;
      /*padding-bottom: 120%; no more needed*/
    }
    .item-right {
      background: tomato;
      padding-bottom: 60%;
    }
    .item-right:nth-child(2) {
      grid-area:r1;
    }
    .item-right:nth-child(3) {
      grid-area:r2;
    }
    .item-right:nth-child(4) {
      grid-area:r3;
    }
    
    @keyframes change{
      to{width:300px;}
    }
    <div class="grid">
      <div class="item-left"></div>
      <div class="item-right"></div>
      <div class="item-right"></div>
      <div class="item-right"></div>
    </div>

    The code can be simplified like this:

    .grid {
      display: grid;
      grid-template-areas:
        "l r"
        "l r"
        "l r";
      grid-template-columns:3fr 2fr; /*adjust this as you like*/
      grid-gap: 10px;
      width: 200px;
      animation:change 2s infinite alternate linear;
    }
    .item-left {
      grid-area:l;
      background: lightblue;
    }
    .item-right {
      background: tomato;
      padding-bottom: 60%;
    }
    @keyframes change{
      to{width:300px;}
    }
    <div class="grid">
      <div class="item-left"></div>
      <div class="item-right"></div>
      <div class="item-right"></div>
      <div class="item-right"></div>
    </div>