Search code examples
htmlcsscss-grid

Grid in HTML bugging because of <details>


I want this scores list on my page, started to do the html css about it but already encountered a problem that I cannot find anyone else having. It all works fine until I open the details, then the 2 <p> elements above extend down by a lot.

#ScoresList {
    margin: 0 0 0 25px;
}
#ScoresList li {
    margin: 20px 0;
}
.ScoreItem {
    display: grid;
    grid-template-rows: 1fr 1fr;
    grid-template-columns: 1fr 1fr;
    grid-gap: 5px;
}
.ScoreItem__Score {grid-area: 1 / 1 / 2 / 2;}
.ScoreItem__Date {grid-area: 1 / 2 / 2 / 3;}
.ScoreItem__Details {grid-area: 2 / 1 / 3 / 3;}
<ol id="ScoresList">
    <li>
        <div class="ScoreItem">
            <p class="ScoreItem__Score">Score: <span>2500</span></p>
            <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
            <details class="ScoreItem__Details">
                <summary>More details</summary>
                <p>score</p>
                <p>tijd</p>
                <p>aantal fouten</p>
                <p>foutpercentage</p>
                <p>datum</p>
            </details>
        </div>
    </li>
</ol>

Closed

Closed

Opened

Opened


Solution

  • Solution # 1

    Your biggest issue lies in setting the columns via grid-area. The 4 values correspond to: row-start, column-start, row-end, column-end.

    Accordingly, all 3 of your columns have a row-start and a row-end values of 1, since they are 1-row grids (btw, flex would be sufficient). Based on the photo, I set up my example.

    • Score: column-start and column-end will 1
    • Details: column-start and column-end will 2
    • Date: column-start and column-end will 3

    Additionally, to prevent the row from expanding when the details element is expanded, align the items in the row to the baseline.

    This just beautifies the code: Use the repeat() function instead of repeating 1fr.

    #ScoresList {
      margin: 0 0 0 25px;
    }
    #ScoresList li {
      margin: 20px 0;
    }
    .ScoreItem {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-gap: 5px;
      align-items: baseline;
    }
    
    .ScoreItem__Score {
      grid-area: 1 / 1 / 1 / 1;
    }
    .ScoreItem__Date {
      grid-area: 1 / 3 / 1 / 3;
    }
    .ScoreItem__Details {
      /*
        row-start: 1
        column-start: 2
        row-end: 1
        column-end: 2
      */
      grid-area: 1 / 2 / 1 / 2;
    }
    <ol id="ScoresList">
      <li>
        <div class="ScoreItem">
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </div>
      </li>
      <li>
        <div class="ScoreItem">
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </div>
      </li>
    </ol>

    If I misunderstood the photo and this would be a 2-row grid layout, where 'More Details' is indeed a second row, then consider this example of mine:

    #ScoresList {
      margin: 0 0 0 25px;
    }
    #ScoresList li {
      margin: 20px 0;
    }
    .ScoreItem {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-gap: 5px;
      align-items: baseline;
    }
    
    .ScoreItem__Score {
      grid-area: 1 / 1 / 1 / 1;
    }
    .ScoreItem__Date {
      grid-area: 1 / 2 / 1 / 2;
    }
    .ScoreItem__Details {
      /*
        row-start: 2
        column-start: 1
        row-end: 2
        column-end: 2
      */
      grid-area: 2 / 1 / 2 / 2;
      margin: 0 auto; /* or can use text-align: center; */
    }
    <ol id="ScoresList">
      <li>
        <div class="ScoreItem">
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </div>
      </li>
      <li>
        <div class="ScoreItem">
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </div>
      </li>
    </ol>


    Solution # 2

    I think you're just complicating things because of numbering. Assuming you're not statically embedding the data in the code but rather using the results of a query, I would also inject the number via JavaScript into a table. Using a table is by no means outdated for displaying structured data.

    table {
      border-collapse: separate;
      border-spacing: 20px; /* distance between 2 rows */
    }
    
    tr > td {
      vertical-align: baseline;
    }
    <table id="ScoresList">
      <tr class="ScoreItem">
        <td>1.</td>
        <td>
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
        </td>
        <td>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </td>
        <td>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
        </td>
      </tr>
      <tr class="ScoreItem">
        <td>2.</td>
        <td>
          <p class="ScoreItem__Score">Score: <span>2500</span></p>
        </td>
        <td>
          <details class="ScoreItem__Details">
            <summary>More details</summary>
            <p>score</p>
            <p>tijd</p>
            <p>aantal fouten</p>
            <p>foutpercentage</p>
            <p>datum</p>
          </details>
        </td>
        <td>
          <p class="ScoreItem__Date">On: <span>25/03/2024</span></p>
        </td>
      </tr>
    </table>