Is there a supported way to style the tab strip background and New Sheet button

Posted by: averma on 30 July 2026, 1:25 am EST

  • Posted 30 July 2026, 1:25 am EST - Updated 30 July 2026, 1:31 am EST

    Hi SpreadJS Team,

    We are using SpreadJS v18.2.3 and are customizing the workbook UI to match our application’s light and dark themes.

    We are currently using spread.sheetTabStyles.add(…), which allows us to customize the appearance of individual sheet tabs (normal, hover, and active states). However, we would also like to customize the surrounding tab strip UI.

    Specifically, we’d like to know if there is a supported way to style the following:

    The tab strip background (the area surrounding the sheet tabs).

    The New Sheet (+) button (background, icon colour, hover/active states).

    The sheet navigation buttons (previous/next sheet arrows).

    Any other UI elements within the sheet tab strip area.

    We couldn’t find any APIs in the documentation for styling these elements, apart from configuring their visibility (for example, newTabVisible).

    I’ve attached the screenshot for the design we are looking to make.

  • Posted 31 July 2026, 5:50 am EST

    Hi,

    Thanks for the mockup — it’s clear what you’re after for both themes, and yes, this is doable, though most of it sits outside the documented API surface.

    Sheet tabs themselves (normal/hover/active) are covered by sheetTabStyles.add(), as you’ve found. For the tab strip chrome around them — background, +, nav arrows, and the rest — SpreadJS doesn’t expose a documented styling API, but the elements are hooked up to internal CSS classes you can override. Here’s what we can confirm for v18.2.3:

    Element CSS class(es)

    Tab strip background .gc-tabStripBackground

    New Sheet (+) button — hover / pressed .gc-tabStripNewTab-hover, .gc-tabStripNewTab-highlight

    Prev/Next navigation arrows — normal / hover / pressed

    .gc-navButton-normal, .gc-navButton-hover, .gc-navButton-highlight

    Overflow “more” button — hover / pressed .gc-navMoreButton-hover, .gc-navMoreButton-highlight

    “All Sheets” ☰ button — hover / pressed .gc-tab-strip-all-sheets-hover, .gc-tab-strip-all-sheets-highlight

    Resize splitter handle .gc-tabStripResizeBarInner

    A few things worth knowing before you use these:

    .gc-tabStripBackground is a real DOM element, so any CSS property works on it — background-color, gradients, borders, whatever you need.

    The +, nav arrows, overflow, and All Sheets buttons are drawn on canvas, not DOM. SpreadJS reads the computed border-color off these classes at paint time and uses it as the icon’s stroke color, so border-color is effectively the only property with a visible effect. background-color, border-radius, etc. are silently ignored on these.

    The resize handle is a thin line, not a bordered shape, which is why color (not border-color) is the property that moves it.

    A starting point for a light/dark toggle, using your palette in place of these placeholder values:

    /* Light theme */
    .gc-tabStripBackground   { background-color: #f6f6f6; }
    .gc-tabStripResizeBarInner { color: #ababab; }
    .gc-navButton-normal      { border-color: #6b6b6b; }
    .gc-navButton-hover       { border-color: #7b61ff; }
    .gc-navButton-highlight   { border-color: #4b2fd6; }
    .gc-tabStripNewTab-hover     { border-color: #7b61ff; }
    .gc-tabStripNewTab-highlight { border-color: #4b2fd6; }
    .gc-navMoreButton-hover      { border-color: #7b61ff; }
    .gc-navMoreButton-highlight  { border-color: #4b2fd6; }
    .gc-tab-strip-all-sheets-hover     { border-color: #7b61ff; }
    .gc-tab-strip-all-sheets-highlight { border-color: #4b2fd6; }
    
    /* Dark theme — scope under whatever selector drives your dark mode */
    .app-dark .gc-tabStripBackground   { background-color: #1e1b29; }
    .app-dark .gc-tabStripResizeBarInner { color: #55506b; }
    .app-dark .gc-navButton-normal      { border-color: #cfc9e8; }
    .app-dark .gc-navButton-hover       { border-color: #9d85ff; }
    .app-dark .gc-navButton-highlight   { border-color: #5b3fe0; }
    .app-dark .gc-tabStripNewTab-hover     { border-color: #9d85ff; }
    .app-dark .gc-tabStripNewTab-highlight { border-color: #5b3fe0; }
    .app-dark .gc-navMoreButton-hover      { border-color: #9d85ff; }
    .app-dark .gc-navMoreButton-highlight  { border-color: #5b3fe0; }
    .app-dark .gc-tab-strip-all-sheets-hover     { border-color: #9d85ff; }
    .app-dark .gc-tab-strip-all-sheets-highlight { border-color: #5b3fe0; }

    After switching classes or toggling theme, force a redraw so SpreadJS re-reads the computed styles:

    spread.invalidateLayout();
    spread.repaint();

    Best regards,

    Priyam

  • Posted 31 July 2026, 6:20 am EST

    Follow-up to the tab strip theming question above. We implemented the CSS class overrides exactly as documented (.gc-tabStripBackground, .gc-tabStripNewTab-normal/-hover/-highlight, .gc-tabStripResizeBarInner, etc.), including spread.invalidateLayout() + spread.repaint() after each theme change as instructed — but none of the styling is taking visible effect.

    A few things worth checking on your end:

    We’re using the excel2013white skin (import “@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css”). Are the class names you provided specific to a different/default skin, or should they apply identically regardless of skin?

    Could you confirm the exact class names by inspecting a live v18.2.3 + excel2013white build? We don’t see any of the listed classes (gc-tabStripBackground, gc-tabStripNewTab-, gc-navButton-, etc.) present on the tab strip DOM at all when inspecting via browser devtools.

    Separately — is there any supported way to set the New Sheet (+) button’s background color specifically? Your earlier reply noted background-color is silently ignored on that canvas-drawn element (only border-color/icon stroke renders), which means a background visually distinct from the tab strip background isn’t achievable via the documented classes at all. Is there an internal API/property for this, or is it genuinely unsupported?

  • Posted 3 August 2026, 4:43 am EST

    Hi,

    Thank you for the detailed follow-up.

    We reproduced the “no visible effect” scenario using the same SpreadJS v18.2.3 with the excel2013white theme. After investigating the engine source, we verified and corrected the class mapping. Please find the attached working sample. Open the sample and click “Switch to Dark” or “Switch to Light” to observe the behavior: Sample.zip

    Why nothing changed despite calling invalidateLayout() and repaint()

    The tab strip UI is rendered on a canvas, not through DOM elements. During the initial paint, SpreadJS reads the computed styles (getComputedStyle) of the gc-* CSS classes using a temporary hidden element and stores the results in an internal style cache.

    Calling:

    spread.invalidateLayout();

    spread.repaint();

    does not clear this cache. As a result, SpreadJS continues using the cached style values from the initial render.

    The correct API to call after changing the theme or CSS classes is:

    spread.refresh();

    refresh() clears the internal style cache, recalculates the layout, and repaints the workbook, allowing the updated CSS styles to take effect. Please refer to the theme toggle implementation in the attached sample.

    1. Theme/Class Names

    The CSS class names are not theme-specific. They are generated and referenced internally by the SpreadJS engine, and the same class definitions are used across all built-in themes, including excel2013white. We verified that these classes are present in a live SpreadJS v18.2.3 + excel2013white environment.

    You may notice that these classes do not appear in the browser’s Developer Tools. This is expected because they are never applied directly to the tab strip DOM. Instead, SpreadJS creates temporary hidden elements, assigns the corresponding gc-* classes, reads their computed styles using getComputedStyle, and then removes the elements. Therefore, the classes will not appear in the rendered DOM, but styling them through your stylesheet works correctly.

    New Sheet (+) Button Background

    We also confirmed that customizing the background of the New Sheet (+) button is not supported in SpreadJS v18.2.3.

    Based on the engine implementation, the paint routine for the + button only reads the border-color, which is used to draw the icon stroke. The background-color and background-image properties are never consumed, and there is currently no internal API or configuration that allows a separate background to be applied.

    The same limitation applies to the navigation arrows, overflow button, and All Sheets button, as they are also rendered as stroke-only canvas icons.

    The attached sample demonstrates the verified class mapping, overrides both background-image and background-color for the tab strip background, and calls spread.refresh() after each theme change. Reusing the same approach should allow your theme customizations to render correctly with the excel2013white theme in SpreadJS v18.2.3.

    Best regards,

    Priyam

  • Posted 4 August 2026, 3:36 am EST - Updated 4 August 2026, 3:42 am EST

    Hi, is their any way to apply color to these 2 white parts in the given screenshots ?

    1. The bar containing scrollbar.
    2. top left corner cell

  • Posted 4 August 2026, 8:18 am EST

    Hi,

    We are still investigating the issue at our end. We will let you know about our findings as soon as possible.

    Regards,

    Priyam

  • Posted 5 August 2026, 3:11 am EST

    Hi,

    Thanks for your patience — here’s the confirmed class mapping for both elements.

    Top-left corner cell

    The corner cell (where the row and column headers intersect) is controlled by:

    .gc-corner-normal
    .gc-corner-hover
    .gc-corner-selected
    .gc-corner-triangle-normal
    .gc-corner-triangle-hover
    .gc-corner-triangle-selected

    .gc-corner-normal/-hover/-selected set the cell background for the three interaction states. .gc-corner-triangle-normal/-hover/-selected control the small triangle glyph drawn in the corner.

    Scrollbar container

    The bar that contains the horizontal scrollbar is controlled by:

    .gc-horizontal-scrollbar

    This is a real DOM element, so background-color (and other standard CSS properties) apply directly.

    Regards,

    Priyam

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels