Search code examples
cssreactjshtml-tablecss-tables

How to retain the width of table columns when hiding columns?


I have a table that has six columns, five of which can be hidden based on user selection(s). The issue that I'm having is that when a column is hidden all other columns expand to fill the space that the hidden column occupied. What I would like to occur instead is for the column to just hide and the remaining columns shift to the left while retaining the widths that they were given. None of the answers that I have found on here seem to address this particular issue.

Below is snips of both my js and css along with screen grabs.

js:

      <table className="hours table table-bordered table-sm" table-layout="fixed">
        <thead>
          <tr>
            <th scope="col"
              colSpan="3"
              className="row-dow"
            >
              Hours
            </th>
            <th
              scope="col"
              colSpan="2"
              align="center"
              hidden={this.state.kitchenHoursSame}
              className="row-16"
            >
              Kitchen Hours
            </th>
            <th
              scope="col"
              colSpan="2"
              align="center"
              hidden={!this.state.breakfast}
              className="row-16"
            >
              Breakfast Special
            </th>
            ...
          </tr>
          <tr>
            <th
              scope="col"
            // className="row-8 "
            >
              Day
            </th>
            <th
              scope="col"
              className="row-8"
            >
              Open
            </th>
            <th
              scope="col"
              className="row-8"
            >
              Close
            </th>
            <th
              scope="col"
              hidden={this.state.kitchenHoursSame}
              className="row-8"
            >
              Open
            </th>
            <th
              scope="col"
              hidden={this.state.kitchenHoursSame}
              className="row-8"
            >
              Close
            </th>
            <th
              scope="col"
              hidden={!this.state.breakfast}
              className="row-8"
            >
              1234567890123
            </th>
            <th
              scope="col"
              hidden={!this.state.breakfast}
              className="row-8"
            >
              End
            </th>
            ...
          </tr>
        </thead>
        <tbody>
          {this.state.DOW.map((dowList, i) =>
            <tr>
              <th scope="row" key={dowList.i}>{dowList.long}</th>
              <td>
                <select name="timeofday"
                  value={this.state.timeofday}
                  onChange={this.handleInputChange}>
                  <option>
                    (open)
                  </option>
                </select>
              </td>
              ...
            </tr>
          )}
        </tbody>
      </table>

css:

.hours {
    table-layout: fixed;
    /* width: 90%; */
    width: 1500px;
    white-space: nowrap;
  }
  .hours td {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }


.row-dow {
    width: 20px;
  }
.row-16 {
  width: 16px;
}
.row-8 {
  width: 8px;
}

All columns selected

Kitchen column hidden

Any help would be appreciated even if it is being told that I shouldn't be using tables and should be using something else.


Solution

  • The snippet below shows you how different width defined tables behave when a column is going to be deleted.

    window.addEventListener("load", () => {
      const firstTDs = Array.from(
        document.querySelectorAll("td:nth-child(3)")
      ).concat(Array.from(document.querySelectorAll("th:nth-child(3)")));
    
      document.querySelector(".remove").addEventListener(
        "click",
        () => {
          firstTDs.forEach(td => {
            td.parentNode.removeChild(td);
          });
        },
        { once: true }
      );
    });
    .full-width {
      width: 100%;
    }
    
    .fixed-width {
      width: 600px;
    }
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
    
    
    <h5>Auto width</h5>
    <table class="tbl mdl-data-table mdl-shadow--2dp">
    	<thead>
    		<tr>
    			<th class="mdl-data-table__cell--non-numeric">Material</th>
    			<th>Unit price</th>
    			<th>Quantity</th>
    			<th>Unit price</th>
    		</tr>
    	</thead>
    	<tbody>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
    			<td>$2.90</td>
    			<td>25</td>
    			<td>$2.90</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
    			<td>$1.25</td>
    			<td>50</td>
    			<td>$1.25</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
    			<td>$2.35</td>
    			<td>10</td>
    			<td>$2.35</td>
    		</tr>
    	</tbody>
    </table>
    
    
    <h5>Full width</h5>
    <table class="full-width mdl-data-table mdl-shadow--2dp">
    	<thead>
    		<tr>
    			<th class="mdl-data-table__cell--non-numeric">Material</th>
    			<th>Unit price</th>
    			<th>Quantity</th>
    			<th>Unit price</th>
    		</tr>
    	</thead>
    	<tbody>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
    			<td>$2.90</td>
    			<td>25</td>
    			<td>$2.90</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
    			<td>$1.25</td>
    			<td>50</td>
    			<td>$1.25</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
    			<td>$2.35</td>
    			<td>10</td>
    			<td>$2.35</td>
    		</tr>
    	</tbody>
    </table>
    
    <h5>Fixed width</h5>
    <table class="fixed-width mdl-data-table mdl-shadow--2dp">
    	<thead>
    		<tr>
    			<th class="mdl-data-table__cell--non-numeric">Material</th>
    			<th>Unit price</th>
    			<th>Quantity</th>
    			<th>Unit price</th>
    		</tr>
    	</thead>
    	<tbody>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
    			<td>$2.90</td>
    			<td>25</td>
    			<td>$2.90</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
    			<td>$1.25</td>
    			<td>50</td>
    			<td>$1.25</td>
    		</tr>
    		<tr>
    			<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
    			<td>$2.35</td>
    			<td>10</td>
    			<td>$2.35</td>
    		</tr>
    	</tbody>
    </table>
    
    <h5>Actions</h5>
    
    <button class="remove mdl-button mdl-button--raised">Remove Quantity</button>