Search code examples
csscss-grid

CSS Set grid from multiple columns to only one column


I recently join a web app project. I was tasked with making some parts of the web responsive to mobile view. The Homepage consists of a grid with three columns:

.main {
font-family: "Gentona 300";
height: 100vh;
width: 100%; /* Set height to 100% of viewport height */
display: grid;


overflow: hidden;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: 1fr 0.2fr 2fr 2fr;
grid-template-areas:
    "sidebar header header"
    "sidebar navbar navbar"
    "sidebar main main"
    "sidebar main main";
}

I used media queries to change the layout into a single column like this:

.main {
font-family: "Gentona 300";
height: 100vh;
width: 100%; /* Set height to 100% of viewport height */
display: grid;


overflow: hidden;
grid-template-columns: 1fr;
grid-template-rows: 1fr 0.2fr 2fr 2fr;
grid-template-areas:
"header"
"navbar"
"main"
"main";
}

@media screen and (min-width: 768px) {
    .main {
        grid-template-columns: 1fr 3fr 1fr;
        grid-template-areas:
        "sidebar header header"
        "sidebar navbar navbar"
        "sidebar main main"
        "sidebar main main";
    }
}

Is this the correct way to do it?


Solution

  • Your approach is correct.
    But you can shorten the code by combining grid-template-areas, grid-template-columns and grid-template-rows to grid-template property:

    body {
      margin: 0;
    }
    
    .main {
      height: 100dvh;
      display: grid;
      grid-template:
        "header" 1fr
        "navbar" .2fr
        "main" 4fr
      ;
    }
    
    @media (width >= 768px) {
      .main {
        grid-template:
           "sidebar header" 1fr
           "sidebar navbar" .2fr
           "sidebar main" 4fr
           / 1fr 4fr
        ;
      }
    }
    
    header {
      background: blue;
      grid-area: header;
    }
    
    nav {
      background: yellow;
      grid-area: navbar;
    }
    
    aside {
      background: orange;
      grid-area: sidebar;
      display: none;
    }
    
    @media (width >= 768px){
      aside {
        display: block;
      }
    }
    
    main {
      background: gray;
      grid-area: main;
    }
    <div class="main">
      <header></header>
      <nav></nav>
      <aside></aside>
      <main></main>
    </div>