Search code examples
htmlcssweb

Advanced html table row formatting


I am new to web development and have been struggling for hours trying to fix this issue I'm having.

To keep things short I am working on a personal-use project. I have a table that is not displaying nicely on mobile views:

Screenshot1

This screenshot shows one row of data. What I want to do is have only 3 columns in the table and display timestamp across all three columns.

Something like this (pardon my drawing skills):

enter image description here

White square represents one row of data on my current table. You can see that the timestamp is bottom left anchored and it can span across all 3 columns. Columns are separated with an "invisible" border (I draw it for demo purposes, to represent alignment of columns across the whole table rowspan).

So far my code (.cshtml) looks like this (basic table):

<table class="table table-hover" style="align-content:center">
    <thead>
        <tr>
            <th scope="col">Timestamp</th>
            <th scope="col">Coffee pod</th>
            <th scope="col">Coffee machine</th>
            <th scope="col">Person</th>
        </tr>
    </thead>
    <tbody>
        @{foreach(var consumptionElement in Model.ConsumptionLog)
        {
        <tr>
            <th scope="row">
                <a>@consumptionElement.ConsumptionTimestamp.ToString("dd.MM.yyyy")</a>
                <a>@consumptionElement.ConsumptionTimestamp.ToString("HH:mm:ss")</a>
            </th>
            <td>
                <figure>
                    <img src="@consumptionElement.CoffeePod.PodPictureDisplay" alt="Coffee pod image" width="100px">
                    <figcaption>@consumptionElement.CoffeePod.Name (@consumptionElement.CoffeePod.Brand)</figcaption>
                </figure>
            <td>
                <figure>
                    <img src="@consumptionElement.CoffeeMachine.ImageDisplay" alt="Coffee machine image" width="50px">
                    <figcaption>@consumptionElement.CoffeeMachine.Nickname</figcaption>
                </figure>
            </td>
            <td>
                <figure>
                    <img src="@consumptionElement.Person.ProfilePictureDisplay" alt="Person profile image"
                        width="100px">
                    <figcaption>@consumptionElement.Person.FullName</figcaption>
                </figure>
            </td>
        </tr>
        }}
    </tbody>
</table>

I have been playing around and trying multiple solutions, like placing a table in table, but all that does it messes up the alignment of columns across the table.

Thank you for your help in advance.


Solution

  • CSS Grid works well for the layout of spreading the time stamp table cell below and across the three other table cells in the row. Set the table row to display as a CSS Grid (display: grid;) and use grid-template-areas to layout the row.

    /* Display each table column (i.e. <td> cell) with the 
        same width. Each column takes up 1/3 of the width 
        of the <thead> and <tbody> parent elements.
    */
    thead tr,
    tbody tr {
        display: grid;
        grid-auto-flow: column;
        grid-template-columns: repeat(3, 1fr);
    }
    
    /* Display the time stamp table cell below the
        pod/machine/profile columns and spread the 
        time stamp table cell content across the
        three columns. */
    tbody tr {
        grid-template-areas:
            'pod machine profile'
            'time time time';
    }
    
    td.coffee-pod {
        grid-area: pod;
    }
    
    td.coffee-machine {
        grid-area: machine;
    }
    
    td.profile-picture {
        grid-area: profile;
    }
    
    td.time-stamp {
        grid-area: time;
    }
    

    /* -----------------------------------------
        Table layout 
    */
    
    
    /* https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns */
    
    
    /* Display each table column (i.e. <td> cell) with the 
        same width. Each column takes up 1/3 of the width 
        of the <thead> and <tbody> parent elements.
    */
    
    thead tr,
    tbody tr {
      display: grid;
      grid-auto-flow: column;
      grid-template-columns: repeat(3, 1fr);
    }
    
    
    /* Display the time stamp table cell below the
        pod/machine/profile columns and spread the 
        time stamp table cell content across the
        three columns. */
    
    tbody tr {
      grid-template-areas: 'pod machine profile' 'time time time';
    }
    
    td.coffee-pod {
      grid-area: pod;
    }
    
    td.coffee-machine {
      grid-area: machine;
    }
    
    td.profile-picture {
      grid-area: profile;
    }
    
    td.time-stamp {
      grid-area: time;
    }
    
    td figure {
      display: grid;
    }
    
    
    /* -----------------------------------------
        Table styles 
    */
    
    td img {
      height: 100px;
    }
    
    .coffee-pod img {
      width: 100px;
    }
    
    .coffee-machine img {
      width: 50px;
    }
    
    .profile-picture img {
      width: 100px;
    }
    
    
    /* -----------------------------------------
        Temporary borders for layout display 
    */
    
    tbody td {
      border: 1px solid blue;
    }
    
    tbody td.time-stamp {
      border: 1px solid grey;
    }
    
    tbody td img {
      border: 1px solid green;
    }
    <table class="table table-hover" style="align-content:center">
      <thead>
        <tr>
          <th scope="col">Coffee pod</th>
          <th scope="col">Coffee machine</th>
          <th scope="col">Person</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="time-stamp">
            <a>26.02.2023</a>
            <a>11:30:15</a>
          </td>
          <td class="coffee-pod">
            <figure>
              <img src="/images/coffee-pod.jpg" alt="Coffee pod image">
              <figcaption>Coffee name and brand</figcaption>
            </figure>
            <td class="coffee-machine">
              <figure>
                <img src="/images/coffee-machine.jpg" alt="Coffee machine image">
                <figcaption>Coffee machine nickname</figcaption>
              </figure>
            </td>
            <td class="profile-picture">
              <figure>
                <img src="/images/profile-picture.jpg" alt="Person profile image">
                <figcaption>Person's full name</figcaption>
              </figure>
            </td>
        </tr>
      </tbody>
    </table>