Search code examples
htmlhtml-table

HTML table with mixed rowspan


I'm trying to use HTML to construct a table with three rows (1-3) and three columns (A-C) forming nine "virtual cells" (A1, B1, C1, A2, B2, C2, A3, B3, C3) and apply row spanning so that:

  • cell A1 span all three rows (covering A2 and A3)
  • cell C1 span two rows (covering C2)
  • cell B2 span two rows (covering B3)

This is what I want to see:

Expected

This is the HTML I thought would give me that:

<html>
  <head>
	<style>
	table { border-collapse: collapse; }
	td { border: 1px solid black; padding: 1em; vertical-align: top; }
	</style>
  </head>
  <body>
	<table>
	  <tr><td rowspan="3">A1</td><td>B1</td><td rowspan="2">C1</td></tr>
	  <tr><td rowspan="2">B2</td></tr>
	  <tr><td>C3</td></tr>
	</table>
  </body>
</html>

But that gives me:

Actual

What is the correct way to get what I want? Or is it not possible?

This is for use in technical documentation. It is not a layout issue, the content is semantically a table.


Solution

  • In order to prevent the rows collapsing without the need for additional markup, you can attach a phantom cell to each row with tr::after set to display: table-cell with your cell padding on top and bottom and a unicode blank space:

    tr::after {
      content: '\00a0';
      display: table-cell;
      padding: 1em 0;
    }
    

    Gives you the correct result:

    Example

    It's worth noting that the phantom cell will create a slight gap to the right like this:

    Gap example

    Full snippet

    table {
      border-collapse: collapse;
    }
    
    td {
      border: 1px solid black;
      padding: 1em;
      vertical-align: top;
    }
    
    tr:after {
      content: '\00a0';
      display: table-cell;
      padding: 1em 0;
    }
    <table>
      <tr>
        <td rowspan="3">A1</td>
        <td>B1</td>
        <td rowspan="2">C1</td>
      </tr>
      <tr>
        <td rowspan="2">B2</td>
      </tr>
      <tr>
        <td>C3</td>
      </tr>
    </table>