I made a table with resizable columns. I am setting the width on the th
element. But looks like it won’t allow me to set width below the width of the longest td
.
What I want to do is to allow the columns to resize to a minimum value.
What worked in allowing the td
to be smaller than the content was to set max-width
, however I don’t want to have a max-width
. And if I recall correctly, min-width
doesn’t work on tables.
Do I have anything to do about it? Or in this case it’s better to try and create a table using CSS Grid instead?
My goal is to allow resizing the columns lower than the th
and td
content and show ellipsis instead (with ...
)
activateTableResize();
function activateTableResize() {
let table, tableContainer, resizeable, currentResizeBar, currentTh, tableFirstRow, tableRect, currentResizeBarRect;
document.addEventListener("mousedown", (event) => {
if (event.target.closest('.resize-bar')) {
resizeable = true;
currentResizeBar = event.target;
currentTh = event.target.closest('th');
table = document.getElementById('my-table');
tableContainer = document.getElementById('my-table-container');
tableFirstRow = table.querySelector('tbody tr');
tableRect = tableContainer.getBoundingClientRect();
currentResizeBarRect = currentResizeBar.getBoundingClientRect();
document.querySelector("body").style.cursor = "col-resize";
document.querySelector("body").style.userSelect = "none";
}
});
document.addEventListener("mousemove", (event) => {
if (resizeable) {
if (event.clientX + 5 < tableContainer.getBoundingClientRect().right) {
let distanceMoved = event.clientX - currentTh.getBoundingClientRect().x;
currentTh.style.width = `${distanceMoved}px`;
}
}
});
document.addEventListener("mouseup", (event) => {
document.querySelector("body").style.cursor = "default";
document.querySelector("body").style.userSelect = "default";
resizeable = false;
});
}
#my-table-container {}
#my-table {
margin: 0;
padding: 0;
text-align: left;
border-collapse: collapse;
font-family: sans-serif;
font-size: 0.8rem;
letter-spacing: 1px;
}
#my-table thead {
border-top: 2px solid rgb(140 140 140);
border-left: 2px solid rgb(140 140 140);
}
#my-table th {
position: relative;
margin: 0;
padding: 0;
}
#my-table th:first-child {
width: 150px;
}
#my-table th .resize-bar {
position: absolute;
right: 0;
top: 0;
width: 2px;
height: 100%;
background-color: black;
cursor: col-resize;
}
#my-table tbody td div.cell-container,
#my-table thead th div.cell-container {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
<div id="my-table-container">
<table id="my-table">
<thead>
<tr>
<th scope="col">
<div class="cell-container">Name<span class="resize-bar"><span></div></th>
<th scope="col"><div class="cell-container">Type<span class="resize-bar"><span></div></th>
<th scope="col"><div class="cell-container">Size<span class="resize-bar"></span></div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="cell-container">James Smith</div>
</td>
<td>
<div class="cell-container">20</div>
</td>
<td>
<div class="cell-container">[email protected]</div>
</td>
</tr>
<tr>
<td>
<div class="cell-container">Jane Doe</div>
</td>
<td>
<div class="cell-container">19</div>
</td>
<td>
<div class="cell-container">[email protected]</div>
</td>
</tr>
</tbody>
</table>
</div>