Skip to content

Change the appearance of cells, using custom CSS classes, inline styles, or custom cell borders.

Overview

Handsontable uses the HTML table structure so customization is based either on referencing to the already existing elements, such as TR/TD, or by applying your own CSS classes to HTML elements.

You can format a cell either using a CSS class or with a style applied directly to the DOM element.

Apply custom CSS class styles

In this example, we add a custom class custom-cell to the cell in the top left corner and add a custom-table CSS class that highlights the table headers.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example1');
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1'],
['A2', 'B2', 'C2', 'D2', 'E2'],
['A3', 'B3', 'C3', 'D3', 'E3'],
['A4', 'B4', 'C4', 'D4', 'E4'],
['A5', 'B5', 'C5', 'D5', 'E5'],
],
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
className: 'custom-table',
cell: [
{
row: 0,
col: 0,
className: 'custom-cell',
},
],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example1')!;
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1'],
['A2', 'B2', 'C2', 'D2', 'E2'],
['A3', 'B3', 'C3', 'D3', 'E3'],
['A4', 'B4', 'C4', 'D4', 'E4'],
['A5', 'B5', 'C5', 'D5', 'E5'],
],
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
className: 'custom-table',
cell: [
{
row: 0,
col: 0,
className: 'custom-cell',
},
],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
CSS
td.custom-cell {
color: #fff !important;
background-color: #254ac6 !important;
}
.custom-table thead th:nth-child(even),
.custom-table tbody tr:nth-child(odd) th {
color: #fff !important;
background-color: #254ac6 !important;
}

Apply inline styles

You can apply inline styles directly to the DOM element using its style property. You can use the renderer option to do that.

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import { textRenderer, registerRenderer } from 'handsontable/renderers';
// register Handsontable's modules
registerAllModules();
const customStylesRenderer = (hotInstance, TD, ...rest) => {
textRenderer(hotInstance, TD, ...rest);
TD.style.fontWeight = 'bold';
TD.style.color = 'green';
TD.style.background = '#d7f1e1';
};
registerRenderer('customStylesRenderer', customStylesRenderer);
const container = document.querySelector('#example2');
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1'],
['A2', 'B2', 'C2', 'D2', 'E2'],
['A3', 'B3', 'C3', 'D3', 'E3'],
['A4', 'B4', 'C4', 'D4', 'E4'],
['A5', 'B5', 'C5', 'D5', 'E5'],
],
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
cell: [
{
row: 0,
col: 0,
renderer: 'customStylesRenderer',
},
],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
import { textRenderer, registerRenderer } from 'handsontable/renderers';
import { BaseRenderer } from 'handsontable/renderers';
// register Handsontable's modules
registerAllModules();
const customStylesRenderer: BaseRenderer = (hotInstance, TD, ...rest) => {
textRenderer(hotInstance, TD, ...rest);
TD.style.fontWeight = 'bold';
TD.style.color = 'green';
TD.style.background = '#d7f1e1';
};
registerRenderer('customStylesRenderer', customStylesRenderer);
const container = document.querySelector('#example2')!;
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1'],
['A2', 'B2', 'C2', 'D2', 'E2'],
['A3', 'B3', 'C3', 'D3', 'E3'],
['A4', 'B4', 'C4', 'D4', 'E4'],
['A5', 'B5', 'C5', 'D5', 'E5'],
],
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
cell: [
{
row: 0,
col: 0,
renderer: 'customStylesRenderer',
},
],
height: 'auto',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});

Custom cell borders

To enable the custom borders feature, set the customBorders option. This can either be set as true or initialized as an array with a pre-defined setup. For the list of available settings and methods, visit the API reference.

In the names of the API properties, the words start and end refer to the starting and ending edges of the layout direction.

You can customize the border style using the style property in the border configuration. The available options are:

  • 'solid' (default) - A solid line border
  • 'dashed' - A dashed line border
  • 'dotted' - A dotted line border

The style property can be set for any border edge (top, bottom, start, end). When not specified, it defaults to 'solid'.

The example below demonstrates different border styles applied to various cell ranges:

JavaScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example3');
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1', 'F1'],
['A2', 'B2', 'C2', 'D2', 'E2', 'F2'],
['A3', 'B3', 'C3', 'D3', 'E3', 'F3'],
['A4', 'B4', 'C4', 'D4', 'E4', 'F4'],
['A5', 'B5', 'C5', 'D5', 'E5', 'F5'],
],
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
stretchH: 'all',
height: 'auto',
licenseKey: 'non-commercial-and-evaluation',
customBorders: [
{
range: {
from: {
row: 1,
col: 1,
},
to: {
row: 3,
col: 4,
},
},
top: {
width: 2,
color: '#5292F7',
style: 'dotted',
},
bottom: {
width: 2,
color: 'red',
},
start: {
width: 2,
color: 'orange',
style: 'dashed',
},
end: {
width: 2,
color: 'magenta',
},
},
{
row: 2,
col: 2,
start: {
width: 2,
color: 'red',
},
end: {
width: 1,
color: 'green',
},
},
],
});
TypeScript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const container = document.querySelector('#example3')!;
new Handsontable(container, {
data: [
['A1', 'B1', 'C1', 'D1', 'E1', 'F1'],
['A2', 'B2', 'C2', 'D2', 'E2', 'F2'],
['A3', 'B3', 'C3', 'D3', 'E3', 'F3'],
['A4', 'B4', 'C4', 'D4', 'E4', 'F4'],
['A5', 'B5', 'C5', 'D5', 'E5', 'F5'],
],
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
autoWrapCol: true,
stretchH: 'all',
height: 'auto',
licenseKey: 'non-commercial-and-evaluation',
customBorders: [
{
range: {
from: {
row: 1,
col: 1,
},
to: {
row: 3,
col: 4,
},
},
top: {
width: 2,
color: '#5292F7',
style: 'dotted',
},
bottom: {
width: 2,
color: 'red',
},
start: {
width: 2,
color: 'orange',
style: 'dashed',
},
end: {
width: 2,
color: 'magenta',
},
},
{
row: 2,
col: 2,
start: {
width: 2,
color: 'red',
},
end: {
width: 1,
color: 'green',
},
},
],
});

Related guides

Configuration options

Plugins