Skip to content
Block Kit for React
Esc
↑↓navigate↵open⌘Jpreview
On this page

Theming

Light and dark mode, the --sbk-* CSS custom properties, fonts, and isolation from your app's global styles.

Every color in the stylesheet is a --sbk-* CSS custom property, measured from Slack’s own Block Kit Builder. Dark mode is a matter of which values are active. You rarely need to override them, but they’re there when you do.

Your AppAPP
Matches Slack in light and dark.

Light and dark mode

By default, dark values apply under prefers-color-scheme: dark: the page follows the visitor’s OS setting, same as Slack’s own desktop client.

To force a theme regardless of OS preference, set data-theme on <html> (or any ancestor of your Block Kit content):

<html data-theme="dark"></html>
<html data-theme="light"></html>

data-theme="light" also works as an escape hatch to opt an element back out of dark mode even when the OS prefers it.

The theme prop

<BlockKitProvider theme="light" | "dark"> sets data-theme on a wrapper <div> around its children, useful for previewing both themes side by side on the same page, independent of the OS setting:

<div style={{ display: "flex", gap: 16 }}>
  <BlockKitProvider theme="light">
    <Message blocks={blocks} />
  </BlockKitProvider>
  <BlockKitProvider theme="dark">
    <Message blocks={blocks} />
  </BlockKitProvider>
</div>

Leave theme unset to follow the page’s own data-theme/prefers-color-scheme instead.

CSS custom properties

The full set lives in base.css and Message.css. Override any of them after importing the stylesheet to restyle without touching the components. The main tokens:

PropType
--sbk-font?string

Body font. See Fonts below.

Typestring
Default"Slack-Lato", Lato, sans-serif
--sbk-font-mono?string

Code font.

Typestring
Default"Slack-Roboto-Mono", "Roboto Mono", monospace
--sbk-text?color

Primary text color.

Typecolor
--sbk-muted?color

Secondary/muted text, e.g. timestamps.

Typecolor
--sbk-bg?color

Surface background (message, modal, Home tab).

Typecolor
--sbk-link?color

Link and mention text color.

Typecolor
--sbk-mention-bg?color

Resolved user/channel mention background.

Typecolor
--sbk-primary?color

Primary button background (e.g. modal Submit).

Typecolor
--sbk-danger?color

Danger-styled button background.

Typecolor
--sbk-border?color

Default hairline border color.

Typecolor
--sbk-divider?color

Divider block color.

Typecolor
--sbk-code-text?color

Inline code and fenced code block text.

Typecolor
--sbk-code-bg?color

Inline code and fenced code block background.

Typecolor
--sbk-focus-ring?color

Keyboard focus ring and focused input border.

Typecolor
--sbk-menu-bg?color

Dropdown/select menu background.

Typecolor
--sbk-tooltip-bg?color

Tooltip background.

Typecolor
:root {
  --sbk-primary: #1264a3;
  --sbk-primary-hover: #0b4c80;
}

Fonts

Slack sets body text in Lato and code in Roboto Mono, but Slack’s own font files aren’t redistributable. Install the open-source builds from Fontsource instead:

npm install @fontsource/lato @fontsource/roboto-mono
pnpm add @fontsource/lato @fontsource/roboto-mono
yarn add @fontsource/lato @fontsource/roboto-mono
bun add @fontsource/lato @fontsource/roboto-mono
nub add @fontsource/lato @fontsource/roboto-mono
aube add @fontsource/lato @fontsource/roboto-mono
import "@fontsource/lato/400.css";
import "@fontsource/lato/400-italic.css";
import "@fontsource/lato/700.css";
import "@fontsource/lato/900.css";
import "@fontsource/roboto-mono/400.css";

The stylesheet asks for Slack-Lato first, then falls back to plain Lato, so if you’re already serving Lato yourself (a CDN, self-hosted @font-face), you can skip installing Fontsource: any font-family: Lato declaration is picked up.

Isolation from your app’s global CSS

Every component’s root carries an sbk-root class (portalled dialogs and tooltips get it too), and the stylesheet rolls everything under it back to the browser’s defaults before applying its own rules:

:is(.sbk-root, .sbk-confirm__overlay, .sbk-tooltip)
  :where(:not(svg, svg *, img, video, canvas, iframe, embed, object)) {
  all: revert;
}

This means global resets in your app (Tailwind’s preflight, a docs theme’s heading font, a blanket * { min-width: 0 }) don’t leak into how a block renders, and the reverse: block styles don’t leak into your app either, since everything is scoped under .sbk-root. You don’t need to configure anything for this; it’s automatic once you import @nkootstra/block-kit/styles.css.

Was this page helpful?