Skip to main content

The CSS Stylesheet

The chart is drawn with WebGL, but everything around it is HTML: the pane control bars and dividers, the toolbars, the drawing tools, the study forms and the loading states. That HTML gets its look from one stylesheet, scitrader.css, and you restyle it with ordinary CSS.

Importing the Stylesheet​

Import it once, e.g. in your app's entry file:

import "scichart-scitrader/scitrader.css";

It is plain CSS: nothing in the SDK imports it, so it works with any bundler, or as a <link>. Without it, the controls still work, but look like plain browser buttons. The components set inline only the layout they need to work, such as positions and sizes while dragging; colours, borders, spacing, fonts and hover states all come from the stylesheet.

The Theme's CSS Variables​

The stylesheet takes its colours from the theme, through CSS variables. Each theme colour has one, named --st-<group>-<name>: ui.textMuted is --st-ui-text-muted, chart.loadingTint is --st-chart-loading-tint. Every rule gives a fallback, the dark theme's colour, so a control outside any theme still looks right: var(--st-ui-text, #ffffff).

Where the variables come from:

Writes the variables on
SciFinanceChartPanel, <SciFinanceChartView>The chart's container, for its pane controls, dividers and loading states
MarketDepthPanel, <MarketDepthView>The panel's element
SciTraderThemeProvider (React)A wrapper element, and :root
applyThemeCssVariables(element, theme)Any element you choose: use it for controls outside the chart in plain TypeScript
A parent's variables don't reach inside the chart

The chart and the depth panel write the variables on their own elements, so a variable you set on a parent, e.g. .my-app { --st-ui-accent: orange }, is overridden for everything inside them. To change a variable inside the chart, set it on the elements themselves: .my-app .st-pane-control-bar { --st-ui-accent: orange }. The example's "Theme variables" skin does both.

Use the variables in your own CSS, so your controls follow the theme too:

.my-panel {
background: var(--st-ui-panel, #262334);
color: var(--st-ui-text-muted, #9da2bc);
}

themeToCssVariables(theme) lists every variable and its value. Study colours aren't among them: studies are drawn by WebGL, and get their colours from the theme directly.

Overriding the Stylesheet​

Override its rules in your own CSS, loaded after scitrader.css. Every element has a class, listed below:

/* Round drawing tools */
.my-chart .st-drawing-toolbar__button {
border-radius: 50%;
}

/* A thicker highlight on the drawing tool in use */
.my-chart .st-drawing-toolbar__button[aria-pressed="true"] {
border-width: 2px;
}
  • Scope your rules under a class of your own, such as .my-chart here. It keeps them to one chart, and makes each rule more specific than the one it replaces, so it wins whichever stylesheet loads first.
  • A rule with :not() needs the same :not(). Some scitrader.css rules have one, such as the divider's hover, :hover:not([data-dragging="true"]). Repeat it in yours to stay more specific.
  • States are attributes, not classes. Style :hover, :disabled, aria-pressed on toggles and on the selected button of a group, aria-checked on menu items, aria-expanded on a study list's open card, aria-disabled, and data-dragging="true" on a divider being dragged.
  • Translucent hovers and lines use rgb(var(--st-ui-overlay-rgb) / alpha). The overlay colour is white on dark themes and black on light ones, so the same rule works on both.
  • The crosshair isn't HTML. It is drawn with the chart, so its colours come from the theme's chart group; see Styling the Chart.

TypeScript Example: Restyling the Controls with CSS​

A BTC-USD chart with the drawing tools rail, zoom buttons on each pane, and a control bar when you hover a pane. Each button above the chart puts a different set of CSS rules on the page: rounded, square and flat, or new values for the theme’s CSS variables. Pick a drawing tool, or hover a pane, to see each skin’s states.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import { SciChartSurface } from "scichart";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
DrawingToolbar,
DrawingToolsController,
idbPriceStore,
OHLCStudy,
OnChartButtonsModifier,
RSIStudy,
SciFinanceChartPanel,
VolumeStudy,
} from "scichart-scitrader";

// This example expects this HTML:
// <div style="display: flex; flex-direction: column; height: 100%">
// <div id="skins"></div>
// <div id="skinned" style="display: flex; flex: 1; min-height: 0">
// <div id="tools"></div>
// <div id="chart" style="flex: 1; min-width: 0"></div>
// </div>
// </div>

// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);

// CSS overrides for the SDK's controls. In an app, these rules go in your own stylesheet, loaded
// after scitrader.css. Each skin is scoped under a class on an element around the chart, which keeps
// it to this chart and makes each rule more specific than the scitrader.css rule it replaces
const SKINS: Array<{ name: string; css: string }> = [
{ name: "Default", css: "/* No overrides: scitrader.css alone */" },
{
name: "Rounded",
css: `
/* Round drawing tools */
.skin .st-drawing-toolbar__button { border-radius: 50%; }

/* Pill-shaped zoom buttons and pane control bars */
.skin .st-on-chart-buttons,
.skin .st-pane-control-bar { border-radius: 999px; padding-left: 8px; padding-right: 8px; }
.skin .st-pane-control-bar__button,
.skin .st-on-chart-buttons__button { border-radius: 50%; }`,
},
{
name: "Square and flat",
css: `
/* Square corners, and no borders on idle buttons */
.skin .st-drawing-toolbar__button,
.skin .st-on-chart-buttons,
.skin .st-on-chart-buttons__button,
.skin .st-pane-control-bar,
.skin .st-pane-control-bar__button { border-radius: 0; }
.skin .st-drawing-toolbar__button:not([aria-pressed="true"]) { border-color: transparent; }`,
},
{
name: "Theme variables",
css: `
/* Change the theme's colours for these controls only, through its CSS variables.
The drawing toolbar is outside the chart, so it reads them from any parent: */
.skin {
--st-ui-menu-background: #1f1a12;
--st-ui-selection: #f59e0b;
}

/* The chart writes the theme's variables on its own container, which wins over a parent.
To reach controls inside the chart, set the variables on them: */
.skin .st-pane-control-bar,
.skin .st-on-chart-buttons {
--st-ui-toolbar-background: #1f1a12;
--st-ui-toolbar-active: #f59e0b;
--st-ui-icon: #f59e0b;
}`,
},
];

async function createChart() {
const financeChartPanel = await SciFinanceChartPanel.create(document.getElementById("chart"), {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "3M",
studies: [new OHLCStudy(), new VolumeStudy(), new RSIStudy()],
});
const chart = financeChartPanel.financeApi;

// Controls to restyle: the drawing tools rail...
const drawing = DrawingToolsController.attach(chart);
DrawingToolbar.create(document.getElementById("tools"), drawing, { orientation: "vertical" });

// ...the zoom and pan buttons on every pane, shown all the time so their style is easy to see,
// and each pane's control bar: hover a pane to see it
const withButtons = new Set<SciChartSurface>();
const addButtons = () =>
chart.chartPanes.forEach(({ surface }) => {
if (surface && !withButtons.has(surface)) {
withButtons.add(surface);
surface.chartModifiers.add(new OnChartButtonsModifier({ visible: true }));
}
});
addButtons();
chart.paneConfigured.subscribe(addButtons); // panes added later, e.g. by a new study

// Switch skins: put the picked skin's rules in a <style> element
document.getElementById("skinned").classList.add("skin");
const style = document.head.appendChild(document.createElement("style"));
const bar = document.getElementById("skins");
Object.assign(bar.style, barStyle);
const render = (current: string) =>
bar.replaceChildren(
...SKINS.map((skin) => {
const button = document.createElement("button");
button.textContent = skin.name;
Object.assign(button.style, buttonStyle(skin.name === current));
button.onclick = () => {
style.textContent = skin.css;
render(skin.name);
};
return button;
})
);
render("Default");

// When the page goes away: drawing.detach(); financeChartPanel.cleanup();
return financeChartPanel;
}

// The skin buttons use the theme's CSS variables, with the dark theme's values as fallbacks
const barStyle: Partial<CSSStyleDeclaration> = {
display: "flex",
flexWrap: "wrap",
gap: "4px",
padding: "8px 12px",
background: "var(--st-ui-toolbar-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

const buttonStyle = (selected: boolean): Partial<CSSStyleDeclaration> => ({
padding: "4px 12px",
border: "1px solid var(--st-ui-divider, rgba(255,255,255,0.15))",
borderRadius: "4px",
background: selected ? "var(--st-ui-accent, #5c5cff)" : "var(--st-ui-button-background, #363345)",
color: "var(--st-ui-text, #e8e8ee)",
font: "13px sans-serif",
cursor: "pointer",
});

createChart();

React Example: Restyling the Controls with CSS​

The same in React: the rules go in a <style> element.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import * as React from "react";
import { SciChartSurface } from "scichart";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
idbPriceStore,
ISciFinanceChartPanelApi,
ISciFinanceChartPanelConfig,
OHLCStudy,
OnChartButtonsModifier,
RSIStudy,
VolumeStudy,
} from "scichart-scitrader";
import { DrawingToolbar, SciFinanceChartView, useDrawingTools } from "scichart-scitrader-react";

// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);

// CSS overrides for the SDK's controls. In an app, these rules go in your own stylesheet, loaded
// after scitrader.css. Each skin is scoped under a class on an element around the chart, which keeps
// it to this chart and makes each rule more specific than the scitrader.css rule it replaces
const SKINS: Array<{ name: string; css: string }> = [
{ name: "Default", css: "/* No overrides: scitrader.css alone */" },
{
name: "Rounded",
css: `
/* Round drawing tools */
.skin .st-drawing-toolbar__button { border-radius: 50%; }

/* Pill-shaped zoom buttons and pane control bars */
.skin .st-on-chart-buttons,
.skin .st-pane-control-bar { border-radius: 999px; padding-left: 8px; padding-right: 8px; }
.skin .st-pane-control-bar__button,
.skin .st-on-chart-buttons__button { border-radius: 50%; }`,
},
{
name: "Square and flat",
css: `
/* Square corners, and no borders on idle buttons */
.skin .st-drawing-toolbar__button,
.skin .st-on-chart-buttons,
.skin .st-on-chart-buttons__button,
.skin .st-pane-control-bar,
.skin .st-pane-control-bar__button { border-radius: 0; }
.skin .st-drawing-toolbar__button:not([aria-pressed="true"]) { border-color: transparent; }`,
},
{
name: "Theme variables",
css: `
/* Change the theme's colours for these controls only, through its CSS variables.
The drawing toolbar is outside the chart, so it reads them from any parent: */
.skin {
--st-ui-menu-background: #1f1a12;
--st-ui-selection: #f59e0b;
}

/* The chart writes the theme's variables on its own container, which wins over a parent.
To reach controls inside the chart, set the variables on them: */
.skin .st-pane-control-bar,
.skin .st-on-chart-buttons {
--st-ui-toolbar-background: #1f1a12;
--st-ui-toolbar-active: #f59e0b;
--st-ui-icon: #f59e0b;
}`,
},
];

export function CssOverridesChart() {
const [skin, setSkin] = React.useState(SKINS[0]);
const [api, setApi] = React.useState<ISciFinanceChartPanelApi>();
const { controller } = useDrawingTools(api); // the drawing tools rail

// The zoom and pan buttons on every pane, shown all the time so their style is easy to see
React.useEffect(() => {
if (!api) return undefined;
const chart = api.financeApi;
const withButtons = new Set<SciChartSurface>();
const addButtons = () =>
chart.chartPanes.forEach(({ surface }) => {
if (surface && !withButtons.has(surface)) {
withButtons.add(surface);
surface.chartModifiers.add(new OnChartButtonsModifier({ visible: true }));
}
});
addButtons();
chart.paneConfigured.subscribe(addButtons); // panes added later, e.g. by a new study
return () => chart.paneConfigured.unsubscribe(addButtons);
}, [api]);

// Create the config once per mounted chart: studies are live objects bound to one chart
const config = React.useMemo<ISciFinanceChartPanelConfig>(
() => ({
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "3M",
studies: [new OHLCStudy(), new VolumeStudy(), new RSIStudy()],
}),
[]
);

return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
{/* The picked skin's rules. In an app, they would be in your stylesheet */}
<style>{skin.css}</style>
<div style={barStyle}>
{SKINS.map((s) => (
<button key={s.name} style={buttonStyle(s === skin)} onClick={() => setSkin(s)}>
{s.name}
</button>
))}
</div>
<div className="skin" style={{ display: "flex", flex: 1, minHeight: 0 }}>
<DrawingToolbar controller={controller} orientation="vertical" />
<div style={{ flex: 1, minWidth: 0 }}>
<SciFinanceChartView config={config} onInit={setApi} />
</div>
</div>
</div>
);
}

// The skin buttons use the theme's CSS variables, with the dark theme's values as fallbacks
const barStyle: React.CSSProperties = {
display: "flex",
flexWrap: "wrap",
gap: 4,
padding: "8px 12px",
background: "var(--st-ui-toolbar-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

const buttonStyle = (selected: boolean): React.CSSProperties => ({
padding: "4px 12px",
border: "1px solid var(--st-ui-divider, rgba(255,255,255,0.15))",
borderRadius: 4,
background: selected ? "var(--st-ui-accent, #5c5cff)" : "var(--st-ui-button-background, #363345)",
color: "var(--st-ui-text, #e8e8ee)",
font: "13px sans-serif",
cursor: "pointer",
});

CSS Class Reference​

ComponentClasses
Per-pane control barst-pane-control-bar, __info (your content, Layout), __button, __icon, __separator
Control bar drawer (touch layout)st-pane-control-drawer, __handle, __chevron
Divider between panesst-pane-divider (--touch), __grip
Restore strip for hidden panesst-pane-restore-strip, __chip, __icon
A panest-pane, and st-pane--focused while it has keyboard focus
Candle counterst-candle-counter
Pane loading: skeleton, switch overlay, progress dotsst-pane-skeleton (__block); st-pane-loading-overlay (__shimmer); st-pane-progress, __dots, __dot, __caption
On-chart zoom / pan buttonsst-on-chart-buttons, __button
Annotation quick-edit toolbarst-inline-toolbar, __button, __handle, __separator, __swatch, __value
Drawing toolbarst-drawing-toolbar (--vertical / --horizontal), __button, __divider, __flyout, __heading, __item
Market depth panel (the ladder itself is canvas)st-market-depth, __header, __title, __grouping, __step, __grouping-value, __settings, __body; the hover readout __sweep (--bid / --ask), __sweep-head, __sweep-rows, __sweep-foot
Loading overlays inside the chartst-loading-region, st-historical-load, __spinner
Interval, period and live-tip buttonsst-toggle-group, __button, with st-interval-selector, st-period-selector or st-live-tip-toggle on the group
Candle-type picker and its menust-candle-type-selector, __icon, __chevron; st-candle-type-menu, __item, __icon
Study settings formst-study-form, __section, __section-label, __empty, __footer, __reset
Study listst-study-list, __title, __items, __card, __header, __chevron, __name, __remove, __body, __empty
Form fieldsst-text-field (--labelled, --compact), __label, __input, __adornment, __outline; st-select-field, __label, __box, __select, __arrow
Colour field and its pickerst-color-field (--with-trailing), __label, __swatch, __swatch-color, __trailing; st-color-popover, __picker, __saturation, __hue, __alpha, __hex, __channels, __channel, …
Gradient editorst-gradient-ramp, __label, __bar, __track, __handle, __handle-color, __position
Drawings listst-drawing-list, __header, __title, __clear, __items, __row, __icon, __label, __button, __edit, __delete, __empty
Confirmation dialog ("Clear all")st-confirm-dialog, __panel, __title, __text, __actions, __cancel, __confirm

CSS Variable API​

themeToCssVariables, applyThemeCssVariables, cssVariableName, themeVar and uiVar, with their TSDoc
/**
* The theme as CSS custom properties, for everything drawn with HTML and CSS rather than WebGL:
* the vanilla SDK toolbars and overlays, and the React components' stylesheets.
*
* Names are `--st-<group>-<key>` in kebab case: `ui.textMuted` becomes `--st-ui-text-muted`,
* `chart.loadingTint` becomes `--st-chart-loading-tint`. Study colours are not included; they are
* drawn by WebGL and are applied to the studies directly.
*
* Stylesheets should always give a fallback, `var(--st-ui-text, #ffffff)`, so a component still
* renders outside a themed container.
*/
function themeToCssVariables(theme: ISciTraderTheme): Record<string, string>;
/** `cssVariableName("ui", "textMuted")` → `"--st-ui-text-muted"`. */
function cssVariableName(group: string, key: string): string;
/** Write the theme's CSS variables onto an element, so it and its descendants pick them up. */
function applyThemeCssVariables(element: HTMLElement, theme: ISciTraderTheme): void;
/** `var(--st-ui-text, #ffffff)`: a CSS reference to one theme colour, falling back to its value in `theme`. */
function themeVar(theme: ISciTraderTheme, group: "chart" | "candles" | "market" | "ui", key: string): string;

function uiVar(key: keyof ISciTraderUiColors): string;