Resize columns of a table
Assume that we want to resize any column of the following table:
<table id="resizeMe" class="table">
...
</table>
Prepare the resizer
For each column, we insert a div
element indicating that the associated column can be resized. The resizer element is positioned absolutely inside the column. The CSS styles for them would be as below:
.table th {
position: relative;
}
.resizer {
position: absolute;
top: 0;
right: 0;
width: 5px;
cursor: col-resize;
user-select: none;
}
const table = document.getElementById('resizeMe');
const cols = table.querySelectorAll('th');
[].forEach.call(cols, function (col) {
const resizer = document.createElement('div');
resizer.classList.add('resizer');
resizer.style.height = `${table.offsetHeight}px`;
col.appendChild(resizer);
createResizableColumn(col, resizer);
});
Handle the resizer's events
We are going to implement a function, createResizableColumn
, which accepts two parameters:
col
that represents the table header
resizer
that represents the resizer element within the column
In order to allow user to resize col
, we have to handle three events:
mousedown
on the resizer: Track the current position of mouse
mousemove
on document
: Calculate how far the mouse has been moved, and adjust the width of the column
mouseup
on document
: Remove the event handlers of document
const createResizableColumn = function (col, resizer) {
let x = 0;
let w = 0;
const mouseDownHandler = function (e) {
x = e.clientX;
const styles = window.getComputedStyle(col);
w = parseInt(styles.width, 10);
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
};
const mouseMoveHandler = function (e) {
const dx = e.clientX - x;
col.style.width = `${w + dx}px`;
};
const mouseUpHandler = function () {
document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
};
resizer.addEventListener('mousedown', mouseDownHandler);
};
Highlight the resizer
We can improve the user experience a little bit. When user hovers or clicks on the resizer, it can be hightlighted.
To demonstrate the idea in the most simple way, we add a solid border to the :hover
selector:
.resizer:hover,
.resizing {
border-right: 2px solid blue;
}
The resizing
class is added to the resizer while user clicks and drags the resizer:
const mouseDownHandler = function(e) {
...
resizer.classList.add('resizing');
};
const mouseUpHandler = function() {
...
resizer.classList.remove('resizing');
};
Demo
Resize columns of a table
See also