Search code examples
htmlcsslayoutcss-grid

How to create a specific responsive grid layout that has a unique order to elements?


I'm making a dashboard for a website I'm currently working on and have some questions about grid layout as I've mostly only used flexbox.

As seen in the image below I have 3 <div>'s labelled so you can see how I want the layout to change as the resolution changes to mobile.

Currently, I am using two columns the first for the left side (<div>'s 1 and 3) and right side (<div> 2) but with this I can't create the mobile layout I want.

but I can't see how to make this work since <div> 2 has to slot indetween 1 and 3 when on mobile but take up the entire right side when in a desktop view.

Desired Layout

How could i do this?

This is my current setup but I assume this won't work for what I want:

(Does not contain detailed styling atm, only what is needed to create the basic layout of the 3 <div>'s that I am having trouble with as I don't want to do a lot of styling just to have to change it all if I get a good answer here.)

.dashboard-container {
    display: grid;
    grid-template-columns: 1fr 500px;
    column-gap: 1rem;
    padding: 1rem;
}

.dashboard-left {
    display: grid;
    grid-template-rows: 200px 1fr;
    row-gap: 1rem;
}

<div class="dashboard-container">
    <div class="dashboard-left">
        <div class="left-top">
            <div class="dashboard-overview">
                <p>overview</p>
            </div>
        </div>
        <div class="left-bottom">
            <div class="dashboard-recent">
                <p>recent</p>
            </div>
            <div class="dashboard-notes">
                <p>notes</p>
            </div>
        </div>
    </div>
    <div class="dashboard-right">
        <div class="dashboard-calendar">
            <p>calendar</p>
        </div>
    </div>
</div>

Solution

  • I made a solution to achieve your desired outcome using grid-template and grid-area (see more here).

    Your main dashboard-container will have the grid-template property defined as:

    .dashboard-container {
        display: grid;
        grid-template:
          '. area2'
          '. area2';
    }
    

    And your 2nd dashboard, dashboard-2, will have the area defined as:

    .dashboard-2{
      grid-area: area2;
    }
    

    To get it to respond to mobile, you can use a @media query (see more here) to alter the grid-template:

    @media only screen and (max-width: 600px) {
      .dashboard-container {
         grid-template:
          '.'
          'area2'
          '.';
      }
    }
    

    Full code example (adjust browser width to see mobile):

    .dashboard-container {
        display: grid;
        grid-template:
          '. area2'
          '. area2';
        width: max-content;
        height: max-content;
    }
    
    .dashboard-1 {
        display: grid;
        grid-template-columns: auto auto auto;
        width: max-content;
    }
    
    .dashboard-2{
      grid-area: area2;
      width: 100px;
    }
    
    .dashboard-3{
      display: grid;
      grid-template-columns: auto auto;
      width: max-content;
      height: max-content;
    }
    
    .dashboard-2{
      border: 2px solid black;
    }
    
    .box{
      display: block;
      width: 65.3px;
      height: 50px;
      border: 2px solid black;
    }
    
    .box2{
      display: block;
      width: 100px;
      height: 100px;
      border: 2px solid black;
    }
    
    @media only screen and (max-width: 600px) {
      .dashboard-container {
        display: grid;
         grid-template:
          '.'
          'area2'
          '.';
          width: max-content;
          height: max-content;
      }
      .dashboard-2{
        height: 100px;
        width: 204px;
      }
    }
    <div class="dashboard-container">
        <div class="dashboard-1">
          <div class="box">
          </div>
          <div class="box">
          </div>
          <div class="box">
          </div>
          <div class="box">
          </div>
          <div class="box">
          </div>
          <div class="box">
          </div>
        </div>
        <div class="dashboard-2">
        </div>
        <div  class="dashboard-3">
          <div class="box2">
          </div>
          <div class="box2">
          </div>
        </div>
    </div>