JavaScript

How to Create Resizable Columns of HTML Tables

In this tutorial you’ll learn how to make html table columns resizable using pure JavaScript or CSS. A very simple way to make an HTML table columns resizable is to use the CSS resize property.

1) Using CSS

Resizable Columns
Preview: Resizable Columns of HTML Table using CSS

The CSS resize property allows the user to adjust the size of an HTML element by dragging a handle on its bottom right corner. The property can take different values to specify the direction of resizing, such as horizontal, vertical, both, or none. The property only applies to elements that have overflow property set to scroll, auto, or hidden.

Here is an example of using the resize property on the <th> elements:

th {
 resize:horizontal;
 overflow:auto
}

If your table does not have <th> tags, you can use the following code instead:

table tr:first-child td {
 resize:horizontal;
 overflow:auto
}

So, the combined effect of resize and overflow CSS properties is that the header cells (<th> elements) in the table can be horizontally resized by the user, resulting the entire column becomes narrow or wider than its initial width.

Try it:

Column 1 Column 2 Column 3
Row 1, Cell 1 Row 1, Cell 2 Row 1, Cell 3
Row 2, Cell 1 Row 2, Cell 2 Row 2, Cell 3
Row 3, Cell 1 Row 3, Cell 2 Row 3, Cell 3

The Complete Code:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <style>
  #containter {padding:15px;border:3px solid #000}
  #containter table {border-collapse: collapse;}
  #containter th {resize:horizontal;overflow:auto}
  #containter th, #containter td {border: 1px solid black;padding:8px}
 </style>
</head>
<body>
<div id="containter">
 <table>
  <thead>
   <tr>
    <th>Column 1</th>
    <th>Column 2</th>
    <th>Column 3</th>
   </tr>
  </thead>
  <tbody>
   <tr>
    <td>Row 1, Cell 1</td>
    <td>Row 1, Cell 2</td>
    <td>Row 1, Cell 3</td>
   </tr>
   <tr>
    <td>Row 2, Cell 1</td>
    <td>Row 2, Cell 2</td>
    <td>Row 2, Cell 3</td>
   </tr>
   <tr>
    <td>Row 3, Cell 1</td>
    <td>Row 3, Cell 2</td>
    <td>Row 3, Cell 3</td>
   </tr>
   <!-- Add more rows here -->
  </tbody>
 </table>
</div>
</body>
</html>

2) Using JavaScript

If you want to implement a more dynamic and customizable column resizing functionality for an HTML table, you can achieve that using JavaScript.

First, create a table and style it with CSS:

<style>
*{box-sizing: border-box;}
table{border-collapse:collapse;}
td,th{padding:5px 15px;text-align:left;}
table,th,td{border:1px solid #000;}
</style>

<table id="tableId">
 <thead>
  <tr>
   <th><input type="checkbox" /></th>
   <th>Size</th>
   <th>File</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><input type="checkbox" /></td>
   <td>10Mb</td>
   <td>C:\Users\BrainBell\Desktop\Empty\abc.txt</td>
  </tr>
 </tbody>
</table>
Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

JavaScript code to resize HTML table column

The following code will select all tables and pass them to resizableGrid function.

var tables = document.getElementsByTagName('table');

for (var i=0; i<tables.length;i++){
 resizableGrid(tables[i]);
}

You can change the code If you don’t want to select all tables. For example, to select a single table by id:

var table = document.getElementById('tableId');
resizableGrid(table);

Next, we’ll create the resizableGrid which retrieves the very first row of the table and store all td elements to cols variable using row.children.

function resizableGrid(table) {
 var row = table.getElementsByTagName('tr')[0],
 cols = row ? row.children : undefined;
 if (!cols) return;

We’ll make a div for each column as column selector using createDiv function and pass this div to setListeners function for adding some mouse events listeners.

for (var i=0;i<cols.length;i++){
 var div = createDiv(table.offsetHeight);
 cols[i].appendChild(div);
 cols[i].style.position = 'relative';
 setListeners(div);
}

The createDiv function makes a div with absolute position which sits right side on the column. We’ll use this div as column resizer handle.

function createDiv(height){
 var div = document.createElement('div');
 div.style.top = 0;
 div.style.right = 0;
 div.style.width = '5px';
 div.style.position = 'absolute';
 div.style.cursor = 'col-resize';
 /* remove backGroundColor later */
 div.style.backgroundColor = 'red';
 div.style.userSelect = 'none';
 /* table height */
 div.style.height = height+'px';
 return div;
}

Table preview:

Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

The setListeners function adds mousedown event to provided div element, so, when someone press the mouse button on that div (to resize the column) the mousedown event will trigger, where we store the values of current mouse position, the target column width and the next column width. The mousemove event listener add the difference previous and current mouse position pageX to current and next columns to resize the column. On mouseup event we’ll clear all the stored values.

function setListeners(div){
 var pageX,curCol,nxtCol,curColWidth,nxtColWidth;
 div.addEventListener('mousedown', function (e) {
  curCol = e.target.parentElement;
  nxtCol = curCol.nextElementSibling;
  pageX = e.pageX;
  curColWidth = curCol.offsetWidth
  if (nxtCol)
   nxtColWidth = nxtCol.offsetWidth
 });

 document.addEventListener('mousemove', function (e) {
  if (curCol) {
   var diffX = e.pageX - pageX;
 
   if (nxtCol)
    nxtCol.style.width = (nxtColWidth - (diffX))+'px';

   curCol.style.width = (curColWidth + diffX)+'px';
  }
 });

document.addEventListener('mouseup', function (e) { 
 curCol = undefined;
 nxtCol = undefined;
 pageX = undefined;
 nxtColWidth = undefined;
 curColWidth = undefined;
 });
}

Re-sizeable Table preview, the table width is 100%:

Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

Re-sizeable Table demo 2, the table width is set to auto:

a b c d e
         

Re-sizeable Table demo 3, red color removed:

a b c d e
         

Adding hover effect when mouse over the column selector

We'll add a class to column selector div by editing the createDiv function.

function createDiv(height){
 var div = document.createElement('div');
 div.style.top = 0;
 div.style.right = 0;
 div.style.width = '5px';
 div.style.position = 'absolute';
 div.style.cursor = 'col-resize';
 div.style.userSelect = 'none';
 div.style.height = height+'px';
 div.className = 'columnSelector';
 return div;
}

Now style the columnSelector class:

columnSelector : hover {
 border-right: 2px solid #0000f;
}

Re-sizeable Table demo 4, hover effect:

a b c d e
         
         

Make an HTML table resizable

Complete code:

//var tables = document.getElementsByClassName('flexiCol');
var tables = document.getElementsByTagName('table');
for (var i=0; i<tables.length;i++){
 resizableGrid(tables[i]);
}

function resizableGrid(table) {
 var row = table.getElementsByTagName('tr')[0],
 cols = row ? row.children : undefined;
 if (!cols) return;
 
 table.style.overflow = 'hidden';
 
 var tableHeight = table.offsetHeight;
 
 for (var i=0;i<cols.length;i++){
  var div = createDiv(tableHeight);
  cols[i].appendChild(div);
  cols[i].style.position = 'relative';
  setListeners(div);
 }

 function setListeners(div){
  var pageX,curCol,nxtCol,curColWidth,nxtColWidth;

  div.addEventListener('mousedown', function (e) {
   curCol = e.target.parentElement;
   nxtCol = curCol.nextElementSibling;
   pageX = e.pageX; 
 
   var padding = paddingDiff(curCol);
 
   curColWidth = curCol.offsetWidth - padding;
   if (nxtCol)
    nxtColWidth = nxtCol.offsetWidth - padding;
  });

  div.addEventListener('mouseover', function (e) {
   e.target.style.borderRight = '2px solid #0000ff';
  })

  div.addEventListener('mouseout', function (e) {
   e.target.style.borderRight = '';
  })

  document.addEventListener('mousemove', function (e) {
   if (curCol) {
    var diffX = e.pageX - pageX;
 
    if (nxtCol)
     nxtCol.style.width = (nxtColWidth - (diffX))+'px';

    curCol.style.width = (curColWidth + diffX)+'px';
   }
  });

  document.addEventListener('mouseup', function (e) { 
   curCol = undefined;
   nxtCol = undefined;
   pageX = undefined;
   nxtColWidth = undefined;
   curColWidth = undefined
  });
 }
 
 function createDiv(height){
  var div = document.createElement('div');
  div.style.top = 0;
  div.style.right = 0;
  div.style.width = '5px';
  div.style.position = 'absolute';
  div.style.cursor = 'col-resize';
  div.style.userSelect = 'none';
  div.style.height = height + 'px';
  return div;
 }
 
 function paddingDiff(col){
 
  if (getStyleVal(col,'box-sizing') == 'border-box'){
   return 0;
  }
 
  var padLeft = getStyleVal(col,'padding-left');
  var padRight = getStyleVal(col,'padding-right');
  return (parseInt(padLeft) + parseInt(padRight));

 }

 function getStyleVal(elm,css){
  return (window.getComputedStyle(elm, null).getPropertyValue(css))
 }
};

Visit HTML table resizer demo page to download the minified version of "Table Resizer" script.