Search code examples
htmlcsslayout

CSS layout - grid or flex


I'm trying to create this layout. https://pasteboard.co/K1C5o3k.jpg

I tried to use display: grid but the spacing was strange. What would be the best solution? Use grid or flexbox? How do I achieve this spacing using grid or flexbox?

<div class="wrap">
  <div class="test-grid">
    <div class="card box1">some text</div>
    <div class="card box2">some text</div>
    <div class="card">some text</div>
    <div class="card box4">some text</div>
  </div>
</div>

.wrap {
  max-width: 600px;
}
.test-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 1em;
}
.card {
  background-color: tomato;
  width: 160px;
  min-height: 220px;
}
.box1 {
  margin-top: 40px;
}
.box4 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 3;
}

Solution

  • On your grid layout, I use grid-template-row/columns to define the fraction amount and then grid-template-areas to layout the elements, for each child element you want to define the unique class as its grid-area. You can use gap to control the spacing between the elements. Once you define a height and width for the parent element, the children will fill in their respective fraction, along with any defined gap.

    Then use a media query with flex for your mobile layout. You may need to tweek the CSS a bit to get it to look just as you want, but the following example should do the trick.

    .test-grid {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr 1fr;
      gap: 20px 20px;
      grid-template-areas:
        ". two ." 
        "one two four" 
        "one three four" 
        ". three .";
      width: 100vw;
      height: 100vh;
    }
    
    .one {
      grid-area: one;
     background-color: tomato;
    }
    
    .two {
      grid-area: two;
      background-color: tomato;
    }
    
    .three {
      grid-area: three;
      background-color: tomato;
    }
    
    .four {
      grid-area: four;
      background-color: tomato;
    }
    
    .box {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    @media only screen and (max-width: 600px) {
      .test-grid {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 100vw;
        height: 100vh;
      }
      
      .box {
        width: 100%;
        height: 100%;
      }
    }
    <div class="test-grid">
      <div class="one box">some text</div>
      <div class="two box">some text</div>
      <div class="three box">some text</div>
      <div class="four box">some text</div>
    </div>