skip to Main Content

I’m struggling to think of a nice way to setup my grid items in an HTML page. I have a number of charts, each with a previous and current version. Sometimes they have different heights so I decided to have two columns and as many rows as needed, with the Previous charts on the left and current charts on the right:

<div class="my-grid">
  <div class="chart previous">Previous</div>
  <div class="chart current">Current</div>
  <div class="chart previous">Previous</div>
  <div class="chart current">Current</div>
</div>

However, when I have a narrow screen, I want all the charts in one column, with all the current charts before all the previous charts. I tried some CSS grid but it doesn’t move the charts to the front or the back. I tried using grid-template-areas but then all the charts overlapped.

Here’s a codepen of what I have

If you made the view narrow, the blocks should reorder so all the current orange blocks are on the top, followed by all the previous blocks, with their original order respected.

Here’s an image of the desired wide view (this works right now)

enter image description here

Narrow:

Here's an image of the desired narrow view

How can I make this work with CSS grid, or with some other simple css? I don’t mind rearranging the items in HTML, so long as they are ordered correctly on the display.

3

Answers


  1. Just use grid-auto-flow: column to put your items in their respective columns, then when the width is small enough put them all in one column and tell the "previous" items to come last using order.

    https://codepen.io/Paulie-D/pen/oNRqBpN?editors=1100

    .grid {
      display: grid;
      gap: 16px;
      grid-template-columns: 1fr 1fr;
      grid-auto-flow: column;
    }
    
    .previous {
      grid-column: 1;
      background-color: green;
    }
    
    .current {
      grid-column: 2;
      background-color: orange;
    }
    
    .item {
      border: 1px solid black;
    }
    
    .tall {
      height: 100px;
    }
    
    @media (max-width: 600px) {
     .grid {
       grid-template-columns: 1fr;
     }
    
     .previous {
      grid-column: 1;
      order:1;
     }
    
     .current {
      grid-column: 1;
     }
    }
    <div class="grid">
      <div class="item previous">Previous</div>
      <div class="item current">Current</div>
      <div class="item previous tall">Previous</div>
      <div class="item current">Current</div>
      <div class="item previous">Previous</div>
      <div class="item current">Current</div>
      <div class="item previous">Previous</div>
      <div class="item current tall">Current</div>
    </div>
    Login or Signup to reply.
  2. Use CSS Order Property

    This order property will order your charts just add these into your code

    
    .previous {
        background-color: green;
        order:2;
    }
    
    .current {
        background-color: orange;
        order:1;
    }
    
    

    This will order the current as first and previous as second according to the reference images that you provided.

    For more understanding of this CSS Order Property

    Login or Signup to reply.
  3. Since you mentioned that rearranging the HTML wasn’t an issue, I feel like this is more of a flexbox scenario, though Paulie_D already has you covered for making it work with grid. Seems to make more sense at a glance to have all the like elements together in the HTML structure.

    Put all current elements in one div, all previous elements in another div. Both are flexboxes in column mode.

    Then put a wrapper around these two columns. Also a flexbox, but horizontal for desktop and vertical for mobile. flex-direction on the wrapper is the only thing that needs to change between the two views =)

    <html>
     <head>
      <style>
       .grid {
    display: flex;
    gap: 16px;
       }
    
       .row-current, .row-previous {
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
       }
    
       @media (max-width: 600px) {
    .grid {
        flex-direction: column;
    }
       }
    
       .item {
    border: 1px solid black;
       }
    
       .tall {
    height: 100px;
       }
    
       .previous {
    background-color: green;
       }
    
       .current {
    background-color: orange;
       }
      </style>
     </head>
     <body>
      <div class="grid">
       <div class="row-current">
        <div class="item current">Current</div>
        <div class="item current">Current</div>
        <div class="item current">Current</div>
        <div class="item current tall">Current</div>
       </div>
       <div class="row-previous">
        <div class="item previous">Previous</div>
        <div class="item previous tall">Previous</div>
        <div class="item previous">Previous</div>
        <div class="item previous">Previous</div>
       </div>
      </div>
     </body>
    </html>

    (And as a side benefit, you don’t need to specify the "previous" or "current" class on every item as they can be targeted via their parent instead, i.e. .row-current > .item instead of .item.current.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search