Hide an HTML table column without losing the row labels

Hide optional reading detail without changing the shipments represented by the table.

A four-column reading table becomes easier to scan when an optional note column can be hidden. Hide the header and every corresponding data cell together, and keep the row identifier visible. Hiding only the heading leaves a column of unexplained values underneath it.

Use a fictional shipment table with Shipment, Units, Status, and Internal note columns. Shipment identifies the row. Internal note is optional reading detail; its visibility should not change how many shipments or units the table represents.

Shipment reading view: optional notes and unchanged row totals
Shipment reading view: optional notes and unchanged row totals
Open the full example ↗

Open the complete example · Download the full HTML source

Identify the column by meaning

Put a stable marker on the cells belonging to the optional column. This avoids depending on a numeric child position that changes when someone inserts another column.

<label>
  <input id="notes" type="checkbox" checked>
  Show internal notes
</label>
<table>
  <caption>Fictional shipment review</caption>
  <thead>
    <tr>
      <th scope="col">Shipment</th>
      <th scope="col">Units</th>
      <th scope="col" data-column="note">Internal note</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">S-01</th>
      <td>6</td>
      <td data-column="note">Use side entrance</td>
    </tr>
  </tbody>
</table>

The small snippet omits Status to keep the column-matching operation readable. In the complete example, mark the same optional header and note cells while keeping each shipment's status visible.

Change the whole column in one operation

The browser's hidden property provides a direct way to control whether those elements are rendered.

const checkbox = document.querySelector('#notes');
function updateColumn() {
  for (const cell of document.querySelectorAll('[data-column="note"]')) {
    cell.hidden = !checkbox.checked;
  }
}
checkbox.addEventListener('change', updateColumn);
updateColumn();

Run the function at initialization as well as after a change. The visible table should agree with the checkbox's initial value before the reader touches it.

Check your table CSS does not override the hiding behavior. If your application assigns display to marked cells, retain an explicit [hidden] { display: none; } rule for those cells. Do not replace the cells' contents with empty strings: that loses the value instead of controlling its view.

Keep counts independent of visible columns

For three fictional shipments containing six, four, and five units, the source count is three shipments and fifteen units. Hiding Internal note changes neither answer. The checkbox must not be described as a row filter or a calculation control.

The existing sorting and filtering guide changes row order and row visibility. This control changes a column's visibility while leaving the same records in view. Keep those operations separate if you later add both.

Hiding is not removing private data

The note text remains in the HTML file and can be shown again. A visibility checkbox is not a way to distribute confidential notes safely. Remove information that a recipient should not receive from the actual delivery data and source.

For a review in NOS, use the checkbox to offer a compact reading view of information the recipient is allowed to have. Keep Shipment visible so a request such as “change the note on S-01” still identifies the exact row.

Keep reading