Plan an HTML table with interlocking spans by drawing its full grid first, assigning each merged cell a rectangle, and writing cells only where those rectangles begin. This guide walks through a synthetic example you can create in TextEdit and preview on your Mac.

Define the grid before writing cells

The task is to build one five-column table containing grouped column headings, a cell spanning both rows and columns, and another cell spanning a different number of rows. The labels and content below are illustrative: they represent neutral node blocks arranged by slot.

HTML tables represent multidimensional data. Their cells must cover the table’s grid without overlap. If your intended result is simply a page arrangement of unrelated boxes, the HTML standard directs authors toward layout tools such as CSS Grid instead. Here, each block has a meaningful relationship to its row and column headings, so a table fits the task. HTML Standard: The table element.

Start by naming the smallest columns that exist anywhere in the table. In this example, those columns are Slot, Node A, Node B, Node C, and Note. The Nodes heading will cover three of them; it does not create an additional column.

The two span attributes count the cell’s entire footprint, including its starting position. Thus, colspan="2" covers two columns, while rowspan="2" covers two rows. Applying both creates a two-by-two rectangle. An omitted span defaults to one. MDN: The Table Data Cell element.

“Interlocking” describes how these rectangles fit together. Each individual cell still has a rectangular footprint; a single cell cannot bend around another cell. Think of fitting labeled rectangles onto squared paper.

Make a slot ledger for every row

Use an expanded planning table in which repeated labels show the footprint of one merged cell. Repetition in this ledger does not mean repeating that cell in the HTML. The header section will have two rows; the body will have four.

Planned row Column 1 Column 2 Column 3 Column 4 Column 5
Header 1 Slot Nodes Nodes Nodes Note
Header 2 Slot Node A Node B Node C Note
Body 1 Slot 1 Block P Block P Block Q Note X
Body 2 Slot 2 Block P Block P Block R Note X
Body 3 Slot 3 Block S Block T Block T Note X
Body 4 Slot 4 Block U Block U Block U Note Y

Now record the starting position and dimensions of each merged rectangle. Coordinates here are one-based and restart within each section.

Cell Starts at Rows covered Columns covered
Slot heading Header row 1, column 1 2 1
Nodes heading Header row 1, column 2 1 3
Note heading Header row 1, column 5 2 1
Block P Body row 1, column 2 2 2
Note X Body row 1, column 5 3 1
Block T Body row 3, column 3 1 2
Block U Body row 4, column 2 1 3

This ledger makes the difficult second body row straightforward: Block P already occupies columns 2 and 3, and Note X already occupies column 5. Only Slot 2 and Block R begin there, so that row needs just two cell elements.

Use this procedure for each row:

  1. Mark positions occupied by spans started in earlier rows.
  2. Find the first unoccupied column.
  3. Place the next cell and mark its complete rectangle, including future rows.
  4. Reject a rectangle if any part overlaps an occupied position.
  5. Continue until all five column positions are accounted for.

This procedure is a planning aid derived from the standard’s table model. Browsers advance past occupied starting slots when placing cells, but authors must still avoid overlapping rectangles. Counting the number of cell elements in a row is therefore insufficient. HTML Standard: Processing model.

A useful row check is: carried-over occupied columns + columns covered by newly starting cells = five. Body row 2 has three carried-over positions and two new positions. Body row 3 has one carried-over position and four new positions. Check their actual locations as well as the sum: matching totals alone cannot detect an overlap paired with a gap.

Plan row groups and header relationships

Keep both header rows inside one thead and all four body rows inside one tbody. A cell cannot span across separate row groups. For example, Block P cannot start in one tbody and finish in another. The standard also specifies table child ordering: an optional caption, column groups, an optional thead, body rows, and an optional tfoot. HTML Standard: Tables.

The example defines three column groups: one column for Slot, three for Nodes, and one for Note. The Nodes heading uses scope="colgroup"; its subordinate headings use scope="col". W3C’s irregular-header guidance pairs grouped headings with explicit column-group structure. Tables with Irregular Headers.

Geometry and meaning require separate decisions. Block P covers two slot rows and two node columns, so its intended headings are Slot 1, Slot 2, Nodes, Node A, and Node B. Note X belongs to three slot rows and the Note column.

For these merged data cells, the example makes the associations explicit with id values on header cells and space-separated references in each data cell’s headers attribute. W3C documents this approach for complex tables whose header relationships need explicit identification. Tables with Multi-Level Headers.

Do not merge independent values merely because their text matches. In this synthetic document, Block P deliberately describes one block extending across four positions. If each position instead contains a separate observation, preserve those individual cells so the table retains that distinction.

Create the complete HTML file on your Mac

TextEdit can create the local HTML document. Choose File > New, then Format > Make Plain Text. Paste the complete document below, choose File > Save, and name it span-plan.html. If prompted about the extension, choose Use .html. These are Apple’s documented HTML creation steps. Work with HTML documents in TextEdit on Mac.

This is a complete standalone document with its sample content and styling included. It requires no scripts or external assets.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Interlocking span plan</title>
<style>
body { font-family: system-ui, sans-serif; margin: 2rem; }
table { border-collapse: collapse; }
caption { text-align: left; font-weight: bold; margin-bottom: 1rem; }
th, td { border: 1px solid #555; padding: 0.75rem; text-align: left; }
thead { background: #eee; }
</style>
</head>
<body>
<table>
  <caption>Synthetic node blocks by slot</caption>
  <colgroup span="1"></colgroup>
  <colgroup span="3"></colgroup>
  <colgroup span="1"></colgroup>
  <thead>
    <tr>
      <th rowspan="2" scope="col" id="slot">Slot</th>
      <th colspan="3" scope="colgroup" id="nodes">Nodes</th>
      <th rowspan="2" scope="col" id="note">Note</th>
    </tr>
    <tr>
      <th scope="col" id="a">Node A</th>
      <th scope="col" id="b">Node B</th>
      <th scope="col" id="c">Node C</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row" id="s1">Slot 1</th>
      <td rowspan="2" colspan="2" headers="s1 s2 nodes a b">Block P</td>
      <td headers="s1 nodes c">Block Q</td>
      <td rowspan="3" headers="s1 s2 s3 note">Note X</td>
    </tr>
    <tr>
      <th scope="row" id="s2">Slot 2</th>
      <td headers="s2 nodes c">Block R</td>
    </tr>
    <tr>
      <th scope="row" id="s3">Slot 3</th>
      <td headers="s3 nodes a">Block S</td>
      <td colspan="2" headers="s3 nodes b c">Block T</td>
    </tr>
    <tr>
      <th scope="row" id="s4">Slot 4</th>
      <td colspan="3" headers="s4 nodes a b c">Block U</td>
      <td headers="s4 note">Note Y</td>
    </tr>
  </tbody>
</table>
</body>
</html>

Open the saved file in a browser on your Mac. Compare it with the ledger: Block P should extend through Slots 1 and 2 under Nodes A and B; Note X should extend through Slots 1–3; Block T should cover Nodes B and C only in Slot 3. Those three checks distinguish the intended interlocking pattern from a table that merely has a rectangular outline.

If reopening the file in TextEdit shows formatted content, choose File > Open, select the file, click Show Options, and select Ignore rich text commands. For subsequent editing, Apple also documents TextEdit > Settings > Open and Save, where you can enable Display HTML files as HTML code instead of formatted text. Apple’s TextEdit HTML guide.

Diagnose errors and update the plan without losing structure

When the result differs from your plan, inspect the first incorrect row and the rectangles carried into it. Use the following checks before changing spacing or styling.

Symptom What to inspect Correction for this example
An unexpected extra column Cells added where an earlier span already occupies space Body row 2 contains only Slot 2 and Block R; remove any filler cells there
Block R appears under the wrong node Block P’s width and height Confirm Block P has both rowspan="2" and colspan="2"
Note X ends after Slot 2 Its row count Set its span to three rows
Header tiers do not align The first header row and second-row cell count Slot and Note span two rows; the second header row contains only the three node headings
A merged cell has incomplete headings Its headers references Compare every covered row and column against the ledger

An empty cell is appropriate when a position represents an actual empty value. It is not needed for a position already occupied by a spanning cell. MDN’s cell documentation explains that ordinary cells fit into available positions and that spans must not overlap. MDN: The Table Data Cell element.

For this fixed example, use explicit positive row counts. The special value rowspan="0" means the remaining rows of the current row group, so adding a row can extend that cell’s coverage. Use that value only when “through the end of this group” expresses the intended relationship. MDN: Row span behavior.

Before inserting, deleting, or reordering a row, update the ledger. If a new row is inserted between Slots 1 and 2 and Block P should include it, increase Block P’s span and add the new row heading to its headers list. Reconsider Note X independently: the same insertion may also change its intended coverage. Reordering rows requires the same review because the span follows document position.

If the content no longer forms understandable rectangles, simplify its presentation. W3C recommends considering smaller tables when multiple header levels make one table difficult to understand. Tables with Multi-Level Headers.

Keep the slot ledger beside the source as you revise the document. For each change, establish the intended rectangles, write cells only at their starting positions, and check the associated headings. That gives you a repeatable way to preserve both the table’s shape and the relationships its content expresses.

Sources