Home > front end >  Why do inputs affect table cell widths, making them all equal?
Why do inputs affect table cell widths, making them all equal?

Time:03-17

There's a table with table-layout: auto; and each column can have an input to filter it's contents, these filters are optional so there's a feature to hide them.

Problem is - every time user shows/hides inputs layout of the table shifts and it's irritating. Normally table is wide enough for inputs to fit, so it doesn't make sense why layout shifts even if inputs have a very small width.

const input_row = document.getElementById('input_row');
const toggle_btn = document.getElementById('toggle_btn');
let shown = true;
toggle_btn.onclick = function toggle() {
  if (shown) {
    input_row.removeAttribute('hidden')
  } else {
    input_row.setAttribute('hidden', '');
  }
  shown = !shown
}
table * {
  border: 1px solid gray;
}

table {
  width: 700px;
  table-layout: auto;
}

input {
  min-width: 0px;
  width: 10%;
}
<button id="toggle_btn">
  Show/hide inputs
</button>
<p/>
<table>
  <thead>
    <tr>
      <th> Full Name </th>
      <th> Phone </th>
      <th> Id</th>
    </tr>
    <tr id="input_row" hidden>
      <th>
        <input>
      </th>
      <th>
        <input>
      </th>
      <th>
        <input>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lorem, ipsum</td>
      <td> 1 463 123 444</td>
      <td>13 </td>
    </tr>
    <tr>
      <td>Eaque iure</td>
      <td> 1 999 00 22 333</td>
      <td>37</td>
    </tr>
  </tbody>
</table>

Giving inputs position:absolute; stops them from affecting layout but introduces it's own set of problems.

Ideally each column would stay the width it was while inputs were hidden, and inputs would fill the available space. Is there a way to do it without controlling widths with JavaScript?

Also I don't understand why it's happening so if you could explain that'd be nice.

Edit: this is a table component that has to be dynamic, it's content and columns may vary, so a specific width cannot be set.

CodePudding user response:

According to this answer, you must use the size attribute to the input elements. Also, instead of using the hidden attribute, you must use a CSS class having the visibility: collapse property set when the row must be hidden.

const input_row = document.getElementById('input_row');
const toggle_btn = document.getElementById('toggle_btn');
let shown = true;
toggle_btn.onclick = function toggle() {
  if (shown) {
    input_row.classList.remove('hidden')
  } else {
    input_row.classList.add('hidden');
  }
  shown = !shown
}
table * {
  border: 1px solid gray;
}

table {
  width: 700px;
  table-layout: auto;
}

input {
  min-width: 0px;
  width: 10%;
  display: inline-block;
}

.hidden {
  visibility: collapse;
}
<button id="toggle_btn">
  Show/hide inputs
</button>
<p/>
<table>
  <thead>
    <tr>
      <th> Full Name </th>
      <th> Phone </th>
      <th> Id</th>
    </tr>
    <tr id="input_row" >
      <th>
        <input size="1" />
      </th>
      <th>
        <input size="1" />
      </th>
      <th>
        <input size="1" />
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lorem, ipsum</td>
      <td> 1 463 123 444</td>
      <td>13 </td>
    </tr>
    <tr>
      <td>Eaque iure</td>
      <td> 1 999 00 22 333</td>
      <td>37</td>
    </tr>
  </tbody>
</table>

CodePudding user response:

You can try something like that not sure is what you meant though

const input_row = document.getElementById('input_row');
const toggle_btn = document.getElementById('toggle_btn');
let shown = true;
toggle_btn.onclick = function toggle() {
  if (shown) {
    input_row.removeAttribute('hidden')
  } else {
    input_row.setAttribute('hidden', '');
  }
  shown = !shown
}
table * {
  border: 1px solid gray;
}

table {
  width: 700px;
  table-layout: auto;
}
th{
min-width : 100px;

}
input {
  min-width: 10px;
  max-width: 90px;
}
<button id="toggle_btn">
  Show/hide inputs
</button>
<p/>
<table>
  <thead>
    <tr>
      <th> Full Name </th>
      <th> Phone </th>
      <th> Id</th>
    </tr>
    <tr id="input_row" hidden>
      <th>
        <input>
      </th>
      <th>
        <input>
      </th>
      <th>
        <input>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lorem, ipsum</td>
      <td> 1 463 123 444</td>
      <td>13 </td>
    </tr>
    <tr>
      <td>Eaque iure</td>
      <td> 1 999 00 22 333</td>
      <td>37</td>
    </tr>
  </tbody>
</table>

  • Related