Search code examples
htmlcsslayoutresponsive-designcss-grid

I want to design a layout with CSS grid by creating a grid area, but layout does not work as required


I am learning to design a layout with CSS grid.

Here is a Codepen link of my code.

And here is a layout image on Github.

I want to insert one more row with three columns above the footer with this CSS code which is responsible for the layout:

grid-template-areas:
    "nav nav nav"
    "sidebar mycover mycover"
    "sidebar main content1"
    /* "main main main" */    // I don't know why this does not work
    "footer footer footer";

When the new fourth row code "main main main" is commented out, the layout works fine like the image link I gave above. But when I uncomment "main main main", the layout crashes and nothing is displayed. What is the problem?

body {
  margin: 0px;
  padding: 0px;
}

.item {
  background-color: #1eaafc;
  background-image: linear-gradient( 130deg, #6c52d9 0%, #1eaafc 85%, #3edfd7 100%);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
  color: #ffffff;
  border-radius: 4px;
  /* border: 6px solid #171717; */
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
}

.nav {
  grid-area: nav;
}

.cover {
  grid-area: mycover;
}

.sidebar {
  grid-area: sidebar;
}

.content1 {
  grid-area: content1;
}

.content2 {
  grid-area: main;
}

.footer {
  grid-area: footer;
}

.container {
  border: 5px solid red;
  display: grid;
  width: 100%;
  height: 100vh;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 1fr 1fr 100px 80px;
  grid-template-areas: "nav nav nav" "sidebar mycover mycover" "sidebar main content1"
  /* "main main main" */
  "footer footer footer";
}
<div class="container">
  <div class="item nav">nav</div>
  <div class="item cover">cover</div>
  <div class="item sidebar">sidebar</div>
  <div class="item content1">content1</div>
  <div class="item content2">main</div>
  <div class="item footer">footer</div>
</div>


Solution

  • Each grid area must be a square or a rectangle, 3 x 1 or 2 x 2 or 4 x 2 or 1 x 1, for example. Non-rectangular shapes are not allowed. I added a content2 grid area and a lowercover grid area to your layout to try to demonstrate this more clearly.

    Your main grid area covered just one column and one row, namely the third row. So trying to put three main grid areas covering three columns in the fourth row is not possible.

    I created a new class, orange, by copying background-color and background-image from your item class and swapping the values of the red and blue components (i.e. #1eaafc became #fcaa1e). I applied this orange class to main, lowercover, and content2 and now the orange areas of the grid is what you were trying to achieve with your original code.

    If you want to create a non-rectangular shape on a grid then you need to think about putting another grid or flexbox within your grid. But this may become difficult to manage for multiple different device screen sizes.

    The following answer about grid-template-areas not working explains this very well too.

    Here is a link to a complete guide to CSS grid

    body {
      margin: 0px;
      padding: 0px;
    }
    
    .item {
      background-color: #1eaafc;
      background-image: linear-gradient( 130deg, #6c52d9 0%, #1eaafc 85%, #3edfd7 100%);
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
      color: #ffffff;
      border-radius: 4px;
      border: 2px solid #171717;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 18px;
      font-weight: bold;
    }
    
    .nav {
      grid-area: nav;
    }
    
    .cover {
      grid-area: mycover;
    }
    
    .sidebar {
      grid-area: sidebar;
    }
    
    .lowercover {
      grid-area: lowercover;
    }
    
    .content1 {
      grid-area: content1;
    }
    
    .content2 {
      grid-area: content2;
    }
    
    .footer {
      grid-area: footer;
    }
    
    .main {
      grid-area: main;
    }
    
    .container {
      border: 5px solid red;
      display: grid;
      width: 100%;
      height: 100vh;
      grid-template-columns: 1fr 1fr 1fr;
      grid-template-rows: 100px 1fr 1fr 1fr 80px;
      grid-template-areas: 
        "nav nav nav"
        "sidebar mycover mycover" 
        "sidebar main content1" 
        "lowercover lowercover content2"
        "footer footer footer";
    }
    
    .orange {
      background-color: #fcaa1e;
      background-image: linear-gradient( 130deg, #d9526c 0%, #fcaa1e 85%, #d7df3e 100%);
    }
    <div class="container">
      <div class="item nav">nav</div>
      <div class="item cover">cover</div>
      <div class="item sidebar">sidebar</div>
      <div class="item lowercover orange">lower cover</div>
      <div class="item main orange">main</div>
      <div class="item content1">content1</div>
      <div class="item content2 orange">content2</div>
      <div class="item footer">footer</div>
    </div>