Styling
The suggestion mark renders as a <span> element with data attributes that can be targeted with CSS.
CSS selectors
/* All suggestions */
[data-suggestion] {
/* Base styles for all suggestions */
}
/* Insertions */
[data-suggestion-type="add"] {
background-color: rgba(0, 255, 0, 0.2);
text-decoration: underline;
}
/* Deletions */
[data-suggestion-type="delete"] {
background-color: rgba(255, 0, 0, 0.2);
text-decoration: line-through;
}
/* Replacement deletions (old text being replaced) */
[data-suggestion-type="replaceDeletion"] {
background-color: rgba(255, 0, 0, 0.2);
text-decoration: line-through;
}
/* Replacement insertions (new text replacing old) */
[data-suggestion-type="replaceInsertion"] {
background-color: rgba(0, 255, 0, 0.2);
text-decoration: underline;
}
/* Mark changes (formatting added or removed) */
[data-suggestion-type="markChange"] {
background-color: rgba(255, 200, 0, 0.2);
}
/* Suggested block splits (the block created by a tracked Enter) */
[data-suggestion-type="blockSplit"] {
box-shadow: inset 2px 0 0 rgb(59, 130, 246);
}
/* Style suggestions by user */
[data-suggestion-user="user-123"] {
border-bottom: 2px solid blue;
}Available data attributes
| Attribute | Description |
|---|---|
data-suggestion | Always present on suggestion mark elements |
data-suggestion-id | The unique suggestion ID |
data-suggestion-type | The internal type: 'add', 'delete', 'replaceDeletion', 'replaceInsertion', 'markChange', 'sink', 'lift', or 'blockSplit' |
data-suggestion-user | The ID of the user who created the suggestion |
data-suggestion-created | ISO timestamp when the suggestion was created |
data-suggestion-user-metadata | JSON-serialized user metadata object (only present when userMetadata is set) |
data-suggestion-type holds the internal SuggestionNodeType, not the public one. A block split is blockSplit here, even though the query API reports it as split.
Block split marker
A suggested block split also renders a marker at the end of the block before the split, showing where the break was added. The default marker is a <span> with the class tiptap-tracked-change-split-marker:
.tiptap-tracked-change-split-marker {
color: rgb(59, 130, 246);
opacity: 0.7;
margin-left: 0.15em;
user-select: none;
}Every marker also carries data-tracked-change-split="true", so you can target custom markers too:
[data-tracked-change-split] {
color: rgb(59, 130, 246);
}The marker is a widget, not document content. The extension always sets contenteditable="false" and disables selection and pointer events on it, so it cannot be typed into, selected, or clicked. Use blockSplitMarker to change the character or element, or set it to null to render nothing.
Known limitations
This extension is in active development and will change significantly over the coming months. The following limitations are known and will be addressed in future releases:
- Nesting is supported for inline suggestions only. Nested suggestions spanning whole blocks are out of scope
- Node type changes (e.g. converting a paragraph to a heading) are not tracked
- There is no explicit suggestion mode that renders a separate "clean" document alongside the tracked version