---
title: "Whiteboard styling"
description: "The CSS of the Tiptap Whiteboard board, and the data attributes and CSS variables that style shapes and the stage."
canonical_url: "https://tiptap.dev/docs/editor/whiteboard/api-reference/styling"
---

# Whiteboard styling

The CSS of the Tiptap Whiteboard board, and the data attributes and CSS variables that style shapes and the stage.

The board adds only the CSS that it needs to work. Colors, fonts and cursors are up to your app, which styles the board with the data attributes on its elements.

## The board's CSS

`boardStyles` holds the CSS that the board needs to work: the size of the board and the area around it, how shapes hold their text, outline or component, and where their handles show. The rules are in the `whiteboard` cascade layer, so your app's CSS outside of layers overrides them.

The board adds its CSS when its editor starts, so the `whiteboard` layer comes after the layers that your app declared before, like Tailwind's, and wins over them. To override the board from those layers, declare the `whiteboard` layer first:

```css
/* With Tailwind, before @import 'tailwindcss' */
@layer whiteboard, theme, base, components, utilities;
```

A doc frame is as tall as its document. Its `height: auto !important` also wins over `!important` rules of your app outside of layers.

The board adds this CSS to the page itself, in a `<style data-tiptap-style-whiteboard>` element. It uses the editor's `injectNonce`. An editor with `injectCSS: false` leaves the CSS to your app:

```js
import { boardStyles } from '@tiptap-pro/extension-whiteboard'

const style = document.createElement('style')
style.textContent = boardStyles
document.head.append(style)
```

Shapes have the size of their attributes. An app that sizes a shape by its content also sets `contain: none` on it.

## Zoom

Set `--zoom` to the zoom of the camera on the element that holds the editor. The handles read it to keep their size at every zoom. Divide your own outlines and borders by it too:

```css
[data-shape][data-selected] {
  outline: calc(2px / var(--zoom, 1)) solid #6a00f5;
  outline-offset: calc(2px / var(--zoom, 1));
}
```

## Shapes

Every shape element has `data-shape`, and a `data-type` with the kind of shape: `sticky-note`, `geo`, `free-text`, `freehand`, `doc-frame` or `arrow`. [Custom shapes](https://tiptap.dev/docs/editor/whiteboard/guides/custom-shapes.md) have the `data-type` from their `shapeNodeView`. The board element has `data-type="board"`.

| Attribute              | On                             | Description                                                                                |
| ---------------------- | ------------------------------ | ------------------------------------------------------------------------------------------ |
| `data-id`              | Every shape                    | The id of the shape                                                                        |
| `data-color`           | Shapes with a color            | The name of its color, like `blue`. Custom shapes have it with a `color` attribute         |
| `data-font-size`       | Shapes with text               | `s`, `m`, `l`, `xl` or a name of your own                                                  |
| `data-text-align`      | Shapes with text               | `start`, `center` or `end`                                                                 |
| `data-font`            | Shapes with text               | `sans`, `serif`, `mono` or a name of your own                                              |
| `data-kind`            | Geometric shapes               | `rectangle`, `ellipse`, `diamond` or `triangle`                                            |
| `data-selected`        | Selected shapes                | Present while the shape is selected                                                        |
| `data-editing`         | The edited shape               | Present while its text, or the document of a doc frame, is edited                          |
| `data-remote-selected` | Shapes that other users select | Present while another user selects the shape. That user's color is in `--remote-selection` |
| `data-erasing`         | Every shape                    | Present while the eraser is about to erase the shape                                       |

The `shapeElementAttributes` option of `WhiteboardKit` adds attributes of your own, like the `data-suggestion-*` attributes of [Tracked Changes](https://tiptap.dev/docs/editor/whiteboard/guides/tracked-changes.md).

### Parts of shapes

| Selector                       | Description                                                                                                                |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `[data-shape-content]`         | The element that holds the text of a shape, or the document of a doc frame                                                 |
| `[data-shape-outline]`         | The SVG outline behind the text of a geometric shape. It stretches over the whole shape                                    |
| `[data-shape-handle='resize']` | A resize handle on a corner of a selected shape. `data-corner` is `top-left`, `top-right`, `bottom-left` or `bottom-right` |
| `[data-arrow-handle]`          | A handle on an end of a selected arrow. Its value is `from` or `to`                                                        |
| `[data-shape-component]`       | The element of a custom shape's node view. It has the size of the shape, and so does a `NodeViewWrapper` in it             |
| `[data-shape-interactive]`     | Your mark on parts of a custom shape's component that take their own presses, like the legend of a chart                   |

Arrows and pen lines are drawn in the current color, so set their `color`. The outline of a geometric shape is a path that your CSS fills and strokes:

```css
[data-type='arrow'],
[data-type='freehand'] {
  color: var(--stroke);
}

[data-shape-outline] path {
  fill: var(--fill);
  stroke: var(--stroke);
  stroke-width: 2px;
  vector-effect: non-scaling-stroke;
}
```

## Colors

Shapes, text colors and highlights store the name of a board color, so your CSS decides how each one looks. One way is a few variables for each color:

```css
[data-color='blue'] {
  --stroke: #0d74ce;
  --fill: #ebf5ff;
  --note: #bfe0ff;
}

[data-type='sticky-note'] {
  background: var(--note);
}
```

Text colors are `span` elements with `data-color`, and highlights `mark` elements with `data-color`. See the [example](https://tiptap.dev/docs/editor/whiteboard/examples/simple.md) for the styles of all colors.

To add a color of your own, add its name to the `colors` option of `WhiteboardKit`, and style it like the others:

```js
import { shapeColors, WhiteboardKit } from '@tiptap-pro/extension-whiteboard'

WhiteboardKit.configure({ colors: [...shapeColors, 'brand'] })
```

Commands take any name. The list decides which text colors and highlights pasted HTML keeps: other text colors go away, and other highlights become yellow.

## Stage

`attachStage` marks the stage, so your CSS can show the tool and the pan:

| Attribute   | Description                                                    |
| ----------- | -------------------------------------------------------------- |
| `data-tool` | The active tool, like `select` or `pen`                        |
| `data-pan`  | `ready` while space is held, and `active` while the board pans |

While a drag runs, the stage holds a preview element:

| Selector               | Description                                                                                                                   |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `[data-selection-box]` | The box of a selection drag                                                                                                   |
| `[data-shape-preview]` | The box of a shape while a tool draws it. Its value is the tool, like `note`, and `data-color` holds the chosen color, if any |
| `[data-arrow-preview]` | The line of an arrow while the arrow tool draws it, in the current color                                                      |
| `[data-pen-preview]`   | The line of the pen while it draws, in the current color. `data-color` holds the color of the line                            |

The previews are not scaled with the board, so they need no `--zoom`:

```css
[data-selection-box],
[data-shape-preview] {
  background: rgba(106, 0, 245, 0.1);
  border: 1px dashed #6a00f5;
}

[data-arrow-preview] {
  color: #6a00f5;
}
```

## Keyboard

While keys act on the board, the editor element has `data-keyboard="board"`. While the text of a shape is edited, it doesn't. It stays while the document of a doc frame is edited.

## Read-only

While the board is [read-only](https://tiptap.dev/docs/editor/whiteboard/guides/shapes-and-tools.md#read-only-boards), the editor element has `data-read-only`, and selected shapes show no handles. Use it for cursors that promise a change, like a move cursor on shapes:

```css
.tiptap[data-read-only] [data-shape] {
  cursor: default;
}
```
