Search code examples
csssasscss-selectorscss-grid

CSS (grid) : Reorder col element on mobile dynamically without template-areas


I am trying to dynamically change the order of <div> on mobile without having to hardcode each <div> with a specific class to be then organised using grid-template-areas.

What I have right now :

<div class="grid-container">
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <div class="d"></div>
  <div class="e"></div>
  <div class="f"></div>
</div>
.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: minmax(min-content, max-content);
  grid-template-areas:  "a b"
                        "c d"
                        "e f";

  .a { grid-area: a; }
  .b { grid-area: b; }
  .c { grid-area: c; }
  .d { grid-area: d; }
  .e { grid-area: e; }
  .f { grid-area: f; }

  @media (max-width: 960px) {
      grid-template-columns: 1fr;
      grid-template-areas:  "a"
                            "c"
                            "e"

                            "b"
                            "d"
                            "f";
  }
}

The problem is that each time I need a new "row" I need to assign the new grid-area property to the corresponding col <div> and update the template-areas in the CSS file.

Example of what I have to do if I add a new row :

<div class="grid-container">
  ...
  <div class="g"></div>
  <div class="h"></div>
</div>
.grid-container {
  ...
  grid-template-areas:  "a b"
                        "c d"
                        "e f"
                        "g h"; // NEW

  ...
  .g { grid-area: g; } // NEW
  .h { grid-area: h; } // NEW

  @media (max-width: 960px) {
      ...
      grid-template-areas:  "a"
                            "c"
                            "e"
                            "g"

                            "b"
                            "d"
                            "f"  // NEW
                            "h"; // NEW
  }
}

As you can see this is (obviously) not really a good solution as the row will be populated by an array of data so I have no idea of knowing how many row will there be.

Is there a way to dynamically achieve this ? :s #beMyHero


Solution

  • I’m not sure I understand what you mean.

    If want divided into two parts, can use order & nth-child

    .grid-container {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
    
      @media (max-width: 960px) {
          grid-template-columns: 1fr;
          > div:nth-child(2n) {
            order: 1;
          }
      }
    }