DHTMLX Kanban. Styling columns and custom column menu example
Color-coding columns helps users instantly identify workflow stages. Combined with a custom column menu, users can change column colors on the fly without editing configuration files, useful for teams that want visual customization at runtime.
Live example
const { Kanban, Toolbar, defaultEditorShape } = kanban;
const { cards, cardShape, rows } = getData();
const columns = [
{
label: "Backlog",
id: "backlog",
css: "yellow"
},
{
label: "In progress",
id: "inprogress",
limit: 3, // a limit for the column
strictLimit: true,
css: "red"
},
{
label: "Testing",
id: "testing",
limit: {
// limits for swimlanes
feature: 2,
task: 2
},
css: "blue"
},
{
label: "Done",
id: "done",
css: "green"
}
];
const board = new Kanban("#root", {
columns,
cards,
rows,
rowKey:"type",
columnShape: {
css: (column, cards) => "gray",
menu: {
show: true,
items: [
{
id: "color",
text: "Color",
data: [
{
id:"yellow",
text: "Yellow",
onClick: ({ column }) => changeColumnColor(column, "yellow")
},
{
id:"red",
text: "Red",
onClick: ({ column }) => changeColumnColor(column, "red")
},
{
id:"green",
text: "Green",
onClick: ({ column }) => changeColumnColor(column, "green")
},
{
id:"blue",
text: "Blue",
onClick: ({ column }) => changeColumnColor(column, "blue")
}
]
}
]
}
},
editorShape: defaultEditorShape.filter(e => e.key !== "users"),
});
const toolbar = new Toolbar("#toolbar", { api: board.api });
const changeColumnColor = (column, cssClass) => board.updateColumn({
id: column.id,
column: {
css: cssClass,
},
replace: false
});<!-- custom styles -->
<style>
.wx-kanban .wx-column {
padding: 0 10px;
border-radius: 5pt;
margin-top: 8px;
}
.wx-kanban .wx-label-line {
border: none;
}
.gray {
background: #dadcdd;
}
.yellow {
background: #FFEB84;
}
.red {
background: #FFA29C;
}
.green {
background: #98EBA5;
}
.blue {
background: #BDE9FD;
}
</style>The code applies styling at two levels: static css classes on individual columns (e.g., css: "yellow") and a dynamic css function on columnShape that returns "gray" as a base style. The custom menu is defined in columnShape.menu.items with nested submenu items. Each color option has an onClick handler that calls board.updateColumn with the new CSS class. The replace: false parameter in updateColumn merges the update rather than replacing the entire column object.
Solution overview
- Add
css: "className"to column definitions for initial colors - Set
columnShape.cssto a function for dynamic base styling - Define
columnShape.menu.itemswith nesteddataarrays for submenus - Use
onClickhandlers that callboard.updateColumn({ id, column: { css }, replace: false }) - Define matching CSS classes for each color
Key points
- Two CSS layers: Column-level
cssandcolumnShape.cssboth apply.column.cssis added to the element's class list first, followed by the result ofcolumnShape.css. Which class wins a style conflict depends on the order the CSS rules appear in your stylesheet replace: falseis the default:updateColumnmerges by default. Only the specified properties change. Passingreplace: truewould replace the entire column object, losing other properties likelabelandlimit- Nested menu items: Use the
dataarray property on a menu item to create a submenu (dropdown within dropdown) onClickreceives context: Each menu item'sonClickgets{ column }, the full column object for the clicked column
API reference
- columnShape: Column styling and menu configuration
- updateColumn: Updates a column's properties
Related examples
- Styling rows and swimlane menu
- Column header template
- Custom context menu
- Column and swimlane limits