skip to Main Content

I have the following HTML:

<ul>
  <li>
    <p>A</p>
    <p>B</p>
    <p>C</p
    <p>D</p>
  </li>
  <li>
    <p>AAA</p>
    <p>BBB</p>
    <p>CCC</p
    <p>DDD</p>
  </li>
  <li>
    <p>A</p>
    <p>B</p>
    <p>C</p
    <p>D</p>
  </li>
  <li>
    <p>AAAAAA</p>
    <p>BBBBBB</p>
    <p>CCCCCC</p
    <p>DDDDDD</p>
  </li>
</ul>

The actual number of lis is variable, but each li will always have 4 p tags.

I want to lay it out in a CSS grid:

+--------+--------+--------+--------+
| A      | B      | C      | D      |
+--------+--------+--------+--------+
| AAA    | BBB    | CCC    | DDD    |
+--------+--------+--------+--------+
| A      | B      | C      | D      |
+--------+--------+--------+--------+
| AAAAAA | BBBBBB | CCCCCC | DDDDDD |
+--------+--------+--------+--------+

So the ul has a grid with 4 columns, and each li is a subgrid.

But when when the screen width is less than 650px, I want to switch the layout to a two-column layout, and re-order the p tags:

+--------+--------+
| A      | C      |
+--------+--------+
| B      | D      |
+--------+--------+
| AAA    | CCC    |
+--------+--------+
| BBB    | DDD    |
+--------+--------+
| A      | C      |
+--------+--------+
| B      | D      |
+--------+--------+
| AAAAAA | CCCCCC |
+--------+--------+
| BBBBBB | DDDDDD |
+--------+--------+

This is what I currently have:

ul {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-areas: "a b c d";
}

li {
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
  grid-column: span 4;
}

li p:nth-of-type(1) {
  grid-area: a;
}

li p:nth-of-type(2) {
  grid-area: b;
}

li p:nth-of-type(3) {
  grid-area: c;
}

li p:nth-of-type(4) {
  grid-area: d;
}

@media (max-width: 650px) {
  ul {
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "a c" "b d";
  }

  li {
    grid-row: span 2;
  }
}

The first two rows appear correctly, but after that the "a c" and the "b d" rows overlap each other.

How can I get the layout to not overlap?

2

Answers


  1. ul {
        list-style: none;
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        /* Define 4 columns */
        gap: 10px;
        /* Optional: adds gap between rows/columns */
    }
    
    li {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        /* Each li also has 4 columns */
    }
    
    li p:nth-of-type(1) {
        grid-column: 1;
        /* Position first p in the first column */
    }
    
    li p:nth-of-type(2) {
        grid-column: 2;
        /* Position second p in the second column */
    }
    
    li p:nth-of-type(3) {
        grid-column: 3;
        /* Position third p in the third column */
    }
    
    li p:nth-of-type(4) {
        grid-column: 4;
        /* Position fourth p in the fourth column */
    }
    
    @media (max-width: 650px) {
        ul {
            grid-template-columns: repeat(2, 1fr);
            /* Only 2 columns in the ul */
        }
    
        li {
            grid-template-columns: repeat(2, 1fr);
            /* Each li has 2 columns */
        }
    
        li p:nth-of-type(1),
        /* A and C are in the first column */
        li p:nth-of-type(3) {
            grid-column: 1;
        }
    
        li p:nth-of-type(2),
        /* B and D are in the second column */
        li p:nth-of-type(4) {
            grid-column: 2;
        }
    }
    • In the media query:

    The grid switches to 2 columns for both ul and li. The p elements are repositioned such that A and C are in the first column, and B and D are in the second column.

    Login or Signup to reply.
  2. I wouldn’t use grid-area here, it’s basically an unnecessary complication.

    The switch is pretty simple, just (at the appropriate width) apply grid-auto-flow: column; to the li.

    * {   margin: 0;   padding: 0;  min-width: 0; min-height: 0; box-sizing: border-box; }  ::before, ::after {   box-sizing:inherit; }
    
    ul {
      list-style: none;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: .25em;
    }
    
    li {
      display: grid;
      grid-template-columns: subgrid;
      grid-template-rows: subgrid;
      grid-column: span 4;
        border: 1px solid grey;
    }
    
    
    @media (max-width: 650px) {
      ul {
        grid-template-columns: 1fr 1fr;
      }
    
      li {
        grid-row: span 2;
        grid-auto-flow: column;
      }
    
    }
    <ul>
      <li>
        <p>A</p>
        <p>B</p>
        <p>C</p>
        <p>D</p>
      </li>
      <li>
        <p>AAA</p>
        <p>BBB</p>
        <p>CCC</p>
        <p>DDD</p>
      </li>
      <li>
        <p>A</p>
        <p>B</p>
        <p>C</p>
        <p>D</p>
      </li>
      <li>
        <p>AAAAAA</p>
        <p>BBBBBB</p>
        <p>CCCCCC</p>
        <p>DDDDDD</p>
      </li>
    </ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search