Skip to main content Skip to footer

Advanced Cell Styling and Formatting for JavaScript Spreadsheet Applications

Quick Start Guide
Tutorial Concept Learn advanced cell styling techniques in a JavaScript spreadsheet using SpreadJS. This tutorial shows how to implement dynamic highlights, hover effects, conditional formatting, and validation styles to create interactive spreadsheet UIs.
What You Will Need NPM Package: @mescius/spread-sheets
Controls Referenced SpreadJS - JavaScript Spreadsheet Component
Documentation | Online Demo Explorer

The industry leading JavaScript spreadsheet control, SpreadJS, is widely recognized for delivering Excel-like features along with powerful customization options, making it a top choice for web-based spreadsheet applications. While the official SpreadJS documentation provides solid guidance on basic cell styling, many real-world projects call for more dynamic and interactive styling approaches tailored to user actions and data context.

In this blog post, we’ll dive into advanced cell styling techniques that extend beyond the standard documentation. You’ll learn how to apply dynamic highlights, context-aware formatting, and create reusable style patterns all designed to enhance your spreadsheets’ look and feel. Whether you’re building a custom Excel-like interface or adding rich data visualization features, these practical examples will help you improve user experience and make your SpreadJS applications more engaging and usable.

Advanced Cell Styling & Formatting in JavaScript Spreadsheets

  1. Styling a Cell When It’s Focused
  2. Styling Selection Color with CSS
  3. Multi-Selection Range Styling
  4. Styling Cells Containing Formulas
  5. Styling Invalid Formula Cells
  6. Styling Cells on Hover
  7. Applying Alternating Row Styles
  8. Styling Empty or Required Cells
  9. Styling Row and Column Headers
  10. Conditional Formatting for Dynamic Styling
  11. Reusing Styles with Named Styles

Download a Free Trial of the Industry Leading JavaScript Spreadsheet, SpreadJS, Today!


1. Styling a Cell When It Is Focused

While SpreadJS provides native selection highlighting, developers can customize this experience further by applying a specific background color or style to the focused cell. 

In this example, we use the SelectionChanged event to track when the focused cell changes. Each time the user selects a new cell, we apply a custom style using setStyle(row, col, style) to highlight it and we also remove the style from the previously focused cell. To achieve this, we maintain state using two variables prevRow and prevCol which store the location of the last focused cell so its style can be cleared. Additionally, we apply the same custom style to the initially focused cell when the spreadsheet first loads, ensuring a consistent appearance from the start.

Customize JavaScript Spreadsheet Cell Focus Styling

function initSpread() {
    sheet.setValue(0, 0, "Click on cell you want to highlight");
    // Define the focused style
    const focusedStyle = new GC.Spread.Sheets.Style();
    focusedStyle.backColor = "#e0f7fa"; 
    focusedStyle.borderTop = new GC.Spread.Sheets.LineBorder("blue", GC.Spread.Sheets.LineStyle.thin);
    focusedStyle.borderBottom = new GC.Spread.Sheets.LineBorder("blue", GC.Spread.Sheets.LineStyle.thin);
    focusedStyle.borderLeft = new GC.Spread.Sheets.LineBorder("blue", GC.Spread.Sheets.LineStyle.thin);
    focusedStyle.borderRight = new GC.Spread.Sheets.LineBorder("blue", GC.Spread.Sheets.LineStyle.thin);
    let prevRow = -1;
    let prevCol = -1;
    // Bind SelectionChanged event to apply style on selection
    sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, args) {
        // Clear style from previously focused cell
        if (prevRow >= 0 && prevCol >= 0) {
            sheet.setStyle(prevRow, prevCol, new GC.Spread.Sheets.Style());
        }
        const sel = args.newSelections[0];
        const row = sel.row;
        const col = sel.col;
        prevRow = row;
        prevCol = col;
        // Apply custom focused style
        sheet.setStyle(row, col, focusedStyle);
    });
    // Apply style to initial selection on load
    const selections = sheet.getSelections();
    if (selections && selections.length > 0) {
        const row = selections[0].row;
        const col = selections[0].col;
        prevRow = row;
        prevCol = col;
        sheet.setStyle(row, col, focusedStyle);
    }
}
initSpread();

Try for yourself here in our live Style Focused Cell JS CodeMine sample or check out our documentation.


2. Styling Selection Color with CSS

SpreadJS allows developers to customize the appearance of the selection highlight to better align with your application's design system. While the default selection style works for most scenarios, you may want to use brand-specific colors or improve visibility for accessibility purposes.

In this example, we attempt to style the selection area by targeting the internal .gc-selection class using CSS. The goal is to give selected cells a purple border and a soft violet background, making the active selection clearer and more visually distinct.

Customize JS Spreadsheet Cell Selection Color

.gc-selection {
    border-color: purple;
    background-color: rgba(238, 210, 245, 0.5);
}

Try this yourself with our live Custom Selection Color JS CodeMine.


3. Multi-Selection Range Styling

In this example, we listen to the SelectionChanged event and apply a custom background color (#d9ead3, a soft green) to each selected range. Before applying new styles, we clear any previously applied cell styles to avoid overlapping or leftover highlights.

Set the Multi-Selection Range Styling in Excel-Like JS Applications

function initSpread() {
  const multiSelectStyle = new GC.Spread.Sheets.Style();
    multiSelectStyle.backColor = "#d9ead3";
 sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, args) {
        sheet.suspendPaint();
    // Clear previous styles
        sheet.clear(
            0, 0,
            sheet.getRowCount(),
            sheet.getColumnCount(),
            GC.Spread.Sheets.SheetArea.viewport,
            GC.Spread.Sheets.StorageType.style
        );
        // Apply style to each selected range
        args.newSelections.forEach(function (range) {
            for (let r = range.row; r < range.row + range.rowCount; r++) {
                for (let c = range.col; c < range.col + range.colCount; c++) {
                    sheet.setStyle(r, c, multiSelectStyle);
                }
            }
        });
sheet.resumePaint();
    });
}
initSpread();

Check out live Multi-Selection Range Styling JS CodeMine sample to learn more.


4. Styling Cells Containing Formulas

Highlighting cells that contain formulas can help users distinguish between static values and dynamic calculations, especially in large spreadsheets. SpreadJS allows you to detect when a formula is entered and style the corresponding cell accordingly.

In this example, we listen for the EditEnded event to detect when the user finishes editing a cell. We then check whether the cell contains a formula using getFormula(row, col). If it does, we apply a custom style: a green background, bold font, and subtle top/bottom borders to visually indicate that the cell contains a calculation.

Customize JavaScript Formula Cell Styling

function initSpread() {
    sheet.setValue(0, 0, "Enter a formula and the cell will be styled");
    sheet.bind(GC.Spread.Sheets.Events.EditEnded, function (e, args) {
        const row = args.row;
        const col = args.col;
        const formula = sheet.getFormula(row, col);
        if (formula) {
            // Apply style when formula is present
            const style = new GC.Spread.Sheets.Style();
            style.backColor = "#e8f5e9"; // light green background
            style.font = "bold 12px Segoe UI";
            style.foreColor = "#2e7d32"; // dark green text
            style.borderBottom = new GC.Spread.Sheets.LineBorder("#81c784", GC.Spread.Sheets.LineStyle.thin);
            style.borderTop = new GC.Spread.Sheets.LineBorder("#a5d6a7", GC.Spread.Sheets.LineStyle.hair);
            sheet.setStyle(row, col, style);
        } else {
            //Remove style when formula is removed 
            sheet.setStyle(row, col, new GC.Spread.Sheets.Style());
        }
    });
}
initSpread();

Try for yourself with our JS Formula Cell Style CodeMine sample.


5. Styling Invalid Formula Cells

A common usability enhancement in JS Excel-like applications is visually signaling when a cell contains an invalid formula. SpreadJS provides built-in support for this through CellStatesType.invalidFormula, allowing you to define custom styles that alert users to issues with formula syntax or usage.

In this example, we enable invalid formula detection by setting spread.options.allowInvalidFormula = true. We then use the cellStates.add() method to apply a red dashed border around any cell that contains an invalid formula helping users quickly identify and correct input errors.

Apply Customer Invalid Formula Styling to JavaScript Spreadsheet Cells

initSpread(spread);
function initSpread(spread) {
    // Allow invalid formulas
    spread.options.allowInvalidFormula = true;
    const sheet = spread.getActiveSheet();
    // Add a prompt in cell A1
    sheet.setValue(0, 0, "Type an invalid formula like: =SUM()");  
    // Create the style to apply to invalid formula cells
    const invalidStyle = new GC.Spread.Sheets.Style();
    const dashedRedBorder = new GC.Spread.Sheets.LineBorder('red', GC.Spread.Sheets.LineStyle.mediumDashed);
    invalidStyle.borderTop = dashedRedBorder;
    invalidStyle.borderBottom = dashedRedBorder;
    invalidStyle.borderLeft = dashedRedBorder;
    invalidStyle.borderRight = dashedRedBorder;    
    // Define a range covering the entire sheet
    const fullRange = new GC.Spread.Sheets.Range(0, 0, sheet.getRowCount(), sheet.getColumnCount());
    // Apply the style to cells with invalid formulas
    sheet.cellStates.add(
        fullRange,
        GC.Spread.Sheets.CellStatesType.invalidFormula,
        invalidStyle,
        GC.Spread.Sheets.SheetArea.viewport
    );
}

Try this live JavaScript spreadsheet Invalid Formula Styling demo here.


6. Styling Cells on Hover

Adding hover effects in a JavaScript spreadsheet app makes it easier for users to see where their mouse is, improving how they navigate. Whether for interactive tutorials, validation feedback, or simply a polished UI, hover styling help guide the user’s focus without requiring clicks or input.

In this example, we define a custom style that changes the background and text color when a user hovers over a specific range of cells. We apply the style using GC.Spread.Sheets.CellStatesType.hover.

Customize JS Spreadsheet Cell Hover Styling | SpreadJS Developer Solution

sheet.setValue(0, 0, "Hover over this cell");
sheet.setValue(1, 0, "And this one too");
sheet.setValue(2, 0, "Also this");
sheet.setColumnWidth(0, 200);

var hoverStyle = new GC.Spread.Sheets.Style();
hoverStyle.backColor = "#ffe0e0";
hoverStyle.foreColor = "#990000";

// Define a range (A1:A10)
var hoverRange = new GC.Spread.Sheets.Range(0, 0, 10, 1);
sheet.cellStates.add(
  hoverRange,
  GC.Spread.Sheets.CellStatesType.hover,
  hoverStyle
);

Try this live JavaScript spreadsheet Cell Hover Style demo here.


7. Applying Alternating Row Styles

Alternating row styles are a simple yet powerful way to improve the readability of data-heavy JS spreadsheets. This technique helps users visually group data by applying a different background color to every other row commonly known as zebra striping.

In this example, we manually loop through the rows and apply a light gray background to even-numbered rows (0, 2, 4, ...). This method gives you full control over styling and can be easily adapted for dynamic datasets or custom patterns beyond just two alternating colors.

Set Alternating Row Colors in JavaScript Spreadsheet Control | SpreadJS Example

function initSpread() {
    // Apply alternating row background color
    for (let row = 0; row < 100; row++) {
        if (row % 2 === 0) {
            for (let col = 0; col < 10; col++) {
                const style = new GC.Spread.Sheets.Style();
                style.backColor = "#f9f9f9";
                sheet.setStyle(row, col, style);
            }
        }
    }
}
initSpread();

Check out the online Alternating Row Styles JS spreadsheet demo.


8. Styling Empty or Required Cells

In many spreadsheets, some cells must be filled out by the user. To help users see which cells are empty, we add a red border around those cells. This gives a clear but gentle reminder without stopping the user from typing.

In this example, we use the tag() method to mark every cell as "required", attaching metadata to each cell. We then listen to the EditEnded event to detect when a user finishes editing a cell. If the edited cell is empty, a red border is applied to signal that input is needed. Once the cell contains a valid value, the red border is removed automatically, giving clear visual validation.

Styling Empty or Required Cells in JavaScript Spreadsheet Web Applications

function initSpread() {
    const rowCount = sheet.getRowCount();
    const colCount = sheet.getColumnCount();
    // Mark all cells as required
    for (let row = 0; row < rowCount; row++) {
        for (let col = 0; col < colCount; col++) {
            sheet.getCell(row, col).tag("required");
        }
    }
    // Validate required fields on edit end
    sheet.bind(GC.Spread.Sheets.Events.EditEnded, function (e, args) {
        const row = args.row;
        const col = args.col;
        const cell = sheet.getCell(row, col);
      
        if (cell.tag() === "required") {
            const value = cell.value();
            const style = new GC.Spread.Sheets.Style();
            if (value === undefined || value === null || value === "") {
                const redBorder = new GC.Spread.Sheets.LineBorder("red", GC.Spread.Sheets.LineStyle.thin);
                style.borderTop = redBorder;
                style.borderBottom = redBorder;
                style.borderLeft = redBorder;
                style.borderRight = redBorder;
            } else {
                style.borderTop = null;
                style.borderBottom = null;
                style.borderLeft = null;
                style.borderRight = null;
            }
            sheet.setStyle(row, col, style);
        }
    });
}
initSpread();

Try for yourself with our live Empty Cell Styling JS CodeMine demo.


9. Styling Row and Column Headers

The row and column headers in SpreadJS help users understand the data by showing labels for rows and columns. By default, these headers use a simple gray style, but SpreadJS gives you full control to customize them and better match the visual design of your spreadsheet or application. 

In this example, we apply distinct styles to both row and column headers using setStyle(). The row headers get a blue background with white text, while the column headers are styled with a dark background and gold text, each using bold fonts for clarity.

Customize Excel-Like JavaScript Spreadsheet Row and Column Headers

function initSpread() {
    // Show row and column headers
    sheet.options.rowHeaderVisible = true;
    sheet.options.colHeaderVisible = true;

    // Row header style
    const rowHeaderStyle = new GC.Spread.Sheets.Style();
    rowHeaderStyle.backColor = "#4A90E2";
    rowHeaderStyle.foreColor = "#FFFFFF";
    rowHeaderStyle.font = "bold 13px Segoe UI";
    sheet.setStyle(-1, 0, rowHeaderStyle, GC.Spread.Sheets.SheetArea.rowHeader);

    // Column header style
    const colHeaderStyle = new GC.Spread.Sheets.Style();
    colHeaderStyle.backColor = "#333333";
    colHeaderStyle.foreColor = "#FFD700";
    colHeaderStyle.font = "bold 13px Segoe UI";
    sheet.setStyle(0, -1, colHeaderStyle, GC.Spread.Sheets.SheetArea.colHeader);
}
initSpread();

To learn more check our the online JS CodeMine demo or read our Set Header Color documentation.


10. Conditional Formatting for Dynamic Styling

Conditional formatting in web applications enables dynamic styling based on the values within cells, allowing you to build smarter, more reactive spreadsheet UIs. It’s perfect for scenarios like highlighting errors or trends without having to manually style individual cells. 

In this example, we define a cell style that turns text red and apply it using a conditional formatting rule that targets all negative values in the JS worksheet. The rule is applied to the entire sheet using the special range(-1, -1, -1, -1) syntax.

Programmatically Apply Conditional Formatting to JavaScript Excel-Like Applications

function initSpread() {
    // Add positive and negative data 
    const sampleData = [
        [10, -5, 15],
        [-2, 7, -8],
        [3, -1, 12]
    ];
    for (let r = 0; r < sampleData.length; r++) {
        for (let c = 0; c < sampleData[r].length; c++) {
            sheet.setValue(r, c, sampleData[r][c]);
        }
    }
    // Define style for negative numbers
    const negativeStyle = new GC.Spread.Sheets.Style();
    negativeStyle.foreColor = "red";
    // Define a range that targets the entire sheet
    const fullSheetRange = new GC.Spread.Sheets.Range(-1, -1, -1, -1);
    // Apply conditional formatting rule highlighting negative values in red
    sheet.conditionalFormats.addCellValueRule(
        GC.Spread.Sheets.ConditionalFormatting.ComparisonOperators.lessThan,
        "0", 
        "",  
        negativeStyle,
        [fullSheetRange]
    );
}
initSpread();

Try for yourself here with our Live JS CodeMine demo or learn more here with out Conditional Formatting documentation.


11. Reusing Styles with Named Styles

When many cells use the same formatting, it’s easier to create reusable named styles to keep things organized and simple to manage. Instead of recreating a style object repeatedly, you can define it once, register it globally, and apply it by name wherever needed. 

In this example, we create a named style called “highlightStyle", set its background and text color, and register it using spread.addNamedStyle(). Then we apply it to cell D4 using setStyleName() allowing consistent styling across the spreadsheet with just a single line of code.

Reusing JS Spreadsheet Styles with Named Styles | Developer Solution

function initSpread() {
    // Define a named style
    const highlightStyle = new GC.Spread.Sheets.Style();
    highlightStyle.name = "highlightStyle";
    highlightStyle.backColor = "#ffff99";
    highlightStyle.foreColor = "#000";
    // Add the named style to the workbook
    spread.addNamedStyle(highlightStyle);
    // Apply to cell D4
    sheet.setStyleName(3, 3, "highlightStyle");
}
initSpread();

To learn more, see our JS CodeMine sample and read the Set Named Style documentation.


Download a Free Trial of the Industry Leading JavaScript Spreadsheet, SpreadJS, Today!

Conclusion

By applying these advanced cell styling techniques, you can create more interactive and visually appealing Excel-like spreadsheets in JavaScript applications using SpreadJS. Experience with these methods to enhance your user experience and bring your web-based spreadsheet applications to the next level. Stay tuned for more tips and best practices to make the most of SpreadJS’ powerful features!

Tags:

comments powered by Disqus