Search code examples
htmlcsscss-grid

Reposition cells in HTML Table using CSS Grid


I have a typical 2-column (label-control layout) html table whose layout needs to be changed, using pure CSS (i.e. without altering the html).

html table

Below is the sample html code:

<table class="grid-table-2-col">
    <tbody>
        <tr>
            <td><span class="StdLabel">Label1</span></td>
            <td><input type="text" placeholder="input 1"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label2</span></td>
            <td><input type="text" placeholder="input 2"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label3</span></td>
            <td><input type="text" placeholder="input 3"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label4</span></td>
            <td><input type="text" placeholder="input 4"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label5</span></td>
            <td><input type="text" placeholder="input 5"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label6</span></td>
            <td><input type="text" placeholder="input 6"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label7</span></td>
            <td><input type="text" placeholder="input 7"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label8</span></td>
            <td><input type="text" placeholder="input 8"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label9</span></td>
            <td><input type="text" placeholder="input 9"></td>
        </tr>
        <tr>
            <td><span class="StdLabel">Label10</span></td>
            <td><input type="text" placeholder="input 10"></td>
        </tr>
    </tbody>
</table>

The following CSS does the job, but isn't very flexible to accommodate any number of rows.

.grid-table-2-col > tbody {
    display: grid;
    grid-template-areas: 
        'R1C1 R1C2'
        'R2C1 R2C2'
        'R3C1 R3C2'
        'R4C1 R4C2'
        'R5C1 R5C2'
        'R6C1 R6C2'
        'R7C1 R7C2'
        'R8C1 R8C2'
        'R9C1 R9C2'
        'R10C1 R10C2';
    grid-template-columns: 50% 50%;
    grid-gap: 10px;
    padding: 2px;
}
    .grid-table-2-col > tbody > tr:nth-child(odd) > td:nth-child(1) {grid-area: L1;}
    .grid-table-2-col > tbody > tr:nth-child(odd) > td:nth-child(2) {grid-area: C1;}

    .grid-table-2-col > tbody > tr:nth-child(1) {grid-area: R1C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(2) {grid-area: R1C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(3) {grid-area: R2C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(4) {grid-area: R2C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(5) {grid-area: R3C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(6) {grid-area: R3C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(7) {grid-area: R4C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(8) {grid-area: R4C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(9) {grid-area: R5C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(10) {grid-area: R5C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(11) {grid-area: R6C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(12) {grid-area: R6C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(13) {grid-area: R7C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(14) {grid-area: R7C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(15) {grid-area: R8C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(16) {grid-area: R8C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(17) {grid-area: R9C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(18) {grid-area: R9C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(19) {grid-area: R10C1; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}
    .grid-table-2-col > tbody > tr:nth-child(20) {grid-area: R10C2; display: grid; grid-template-areas: 'L1' 'C1'; grid-template-columns: 100%;}

I want to get rid of its hard-coded nature.

Does anyone have any better ideas to improve this CSS?


Solution

  • If you have to use that exact HTML, you could achieve your desired result using the following code.

    .grid-table-2-col {
      max-width: 500px;
      margin: auto;
    }
    
    .grid-table-2-col tbody {
      display: flex;
      flex-wrap: wrap;
    }
    
    .grid-table-2-col tr {
      width: 50%;
      padding: 5px 10px;
      box-sizing: border-box;
    }
    
    .grid-table-2-col tr td {
      display: block;
    }
    
    .grid-table-2-col input[type="text"] {
      width: 100%;
    }
    <table class="grid-table-2-col">
      <tbody>
        <tr>
          <td><span class="StdLabel">Label1</span></td>
          <td><input type="text" placeholder="input 1"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label2</span></td>
          <td><input type="text" placeholder="input 2"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label3</span></td>
          <td><input type="text" placeholder="input 3"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label4</span></td>
          <td><input type="text" placeholder="input 4"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label5</span></td>
          <td><input type="text" placeholder="input 5"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label6</span></td>
          <td><input type="text" placeholder="input 6"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label7</span></td>
          <td><input type="text" placeholder="input 7"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label8</span></td>
          <td><input type="text" placeholder="input 8"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label9</span></td>
          <td><input type="text" placeholder="input 9"></td>
        </tr>
        <tr>
          <td><span class="StdLabel">Label10</span></td>
          <td><input type="text" placeholder="input 10"></td>
        </tr>
      </tbody>
    </table>