Styling
MdKitEditor can render without package CSS, but most applications should
import the stylesheet once. It gives the editor a reset-resistant markdown
baseline and exposes CSS variables for theme changes.
import "@mp-lb/mdkit/styles.css";Without this stylesheet, the editor still works, but headings, lists, blockquotes, code blocks, spacing, and focus areas are left to your app's CSS.
CSS Resets
Many app frameworks include CSS resets. Tailwind Preflight, for example, removes
default margins and list styling. The package stylesheet restores markdown
editor defaults under .mp-lb-mdkit-markdown-editor, including:
- heading sizes and spacing
- paragraph spacing
- unordered and ordered list markers
- compact list item spacing
- inline code and code block styling
- blockquote styling
- link color
- full-width editor layout
Import the stylesheet after global reset styles when possible:
import "./app.css";
import "@mp-lb/mdkit/styles.css";If your bundler or framework controls CSS order differently, make sure the
mdkit stylesheet is not overridden by a later broad reset such as
ul { list-style: none; }.
Default Styling
The simplest setup is:
import { MdKitEditor } from "@mp-lb/mdkit";
import "@mp-lb/mdkit/styles.css";
export function Editor({ markdown, setMarkdown }) {
return <MdKitEditor value={markdown} onChange={setMarkdown} />;
}The editor fills the available width by default. Use fillHeight only when you
want the editor to fill its parent's height, own its scroll area, and make the
empty area below the last line clickable.
<MdKitEditor fillHeight value={markdown} onChange={setMarkdown} />Custom Styling
The package stylesheet is intentionally controlled through CSS variables. You can override them with a class:
.my-markdown-editor {
--mp-lb-mdkit-background: #ffffff;
--mp-lb-mdkit-foreground: #172033;
--mp-lb-mdkit-muted: #eef1f4;
--mp-lb-mdkit-muted-foreground: #5b6472;
--mp-lb-mdkit-border: #d8dee8;
--mp-lb-mdkit-link: #4f46e5;
--mp-lb-mdkit-font-family: Inter, system-ui, sans-serif;
--mp-lb-mdkit-font-size: 16px;
--mp-lb-mdkit-line-height: 1.7;
--mp-lb-mdkit-surface-padding: 1rem;
--mp-lb-mdkit-block-gap: 0.75rem;
--mp-lb-mdkit-list-item-gap: 0.125rem;
--mp-lb-mdkit-code-background: #eef1f4;
--mp-lb-mdkit-code-radius: 0.35rem;
--mp-lb-mdkit-code-block-radius: 0.75rem;
}<MdKitEditor
className="my-markdown-editor"
value={markdown}
onChange={setMarkdown}
/>You can also pass variables through style when the values are generated at
runtime:
<MdKitEditor
style={{
"--mp-lb-mdkit-font-family": "ui-serif, Georgia, serif",
"--mp-lb-mdkit-font-size": "18px",
"--mp-lb-mdkit-line-height": "1.8",
}}
value={markdown}
onChange={setMarkdown}
/>See MdKitEditorProps for the full component
props.
Class Hooks
The package uses stable mp-lb-mdkit-* class names for all package-owned
markup. These classes are a supported integration point for product-specific
styling. Prefer CSS variables for theme-level changes, and use class hooks when
you need structural changes, component-specific spacing, or state styling.
Editor
MdKitEditor renders the markdown editing surface and the selection bubble
toolbar. The toolbar appears for non-empty text selections while the editor or
toolbar has focus. The search panel appears only when search is enabled and
the user opens it with the find keyboard shortcut.
.mp-lb-mdkit-markdown-editor: root element rendered byMdKitEditor.mp-lb-mdkit-markdown-editor-fill-height: added to the root whenfillHeightis enabled.mp-lb-mdkit-editor-shell: internal editor layout wrapper.mp-lb-mdkit-editor-surface: scroll and background surface around the ProseMirror editor.mp-lb-mdkit-editor-empty: loading or connecting placeholder.mp-lb-mdkit-search-panel: optional document search panel.mp-lb-mdkit-search-input: search text input.mp-lb-mdkit-search-status: search result count.mp-lb-mdkit-search-button: search navigation or close button.mp-lb-mdkit-tiptap: ProseMirror editable element.mp-lb-mdkit-toolbar: selection bubble toolbar.mp-lb-mdkit-toolbar-button: toolbar button.mp-lb-mdkit-toolbar-button-active: added to active toolbar buttons.mp-lb-mdkit-toolbar-divider: toolbar divider.mp-lb-mdkit-collaboration-caret: remote collaboration caret.mp-lb-mdkit-collaboration-caret-label: remote collaborator label
The editor root exposes data-read-only="true" when readOnly is enabled.
Theme Editor
MdKitThemeEditor renders controls for editing a theme object.
.mp-lb-mdkit-theme-editor: root element rendered byMdKitThemeEditor
Document Toolbar
MdKitDocumentToolbar renders document save, restore, and conflict controls.
.mp-lb-mdkit-document-toolbar: root element.mp-lb-mdkit-document-toolbar-status: status text group.mp-lb-mdkit-document-toolbar-error: non-conflict error message.mp-lb-mdkit-document-toolbar-actions: action button group.mp-lb-mdkit-document-toolbar-conflict-trigger: button that opens external conflict UI.mp-lb-mdkit-document-toolbar-conflict: inline conflict action row
The root exposes these state attributes:
data-conflict:"true"when a document conflict existsdata-dirty:"true"when local edits are unsaveddata-save-status: raw save status from the document controllerdata-status: display status normalized for CSS selectors, such as"saved","unsaved-changes","autosave-pending", or"conflict"
Example:
.mp-lb-mdkit-document-toolbar {
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid var(--border);
padding: 0.5rem 0;
}
.mp-lb-mdkit-document-toolbar-status,
.mp-lb-mdkit-document-toolbar-actions,
.mp-lb-mdkit-document-toolbar-conflict {
display: flex;
align-items: center;
gap: 0.5rem;
}
.mp-lb-mdkit-document-toolbar[data-conflict="true"] {
color: #991b1b;
}Conflict Panel
MdKitConflictPanel renders conflict details, previews, and conflict actions.
.mp-lb-mdkit-conflict-panel: root element.mp-lb-mdkit-conflict-panel-content: title, explanatory text, and metadata.mp-lb-mdkit-conflict-panel-error: error text.mp-lb-mdkit-conflict-panel-meta: remote revision metadata.mp-lb-mdkit-conflict-panel-preview: preview area.mp-lb-mdkit-conflict-panel-tabs: preview tab list.mp-lb-mdkit-conflict-panel-tab: preview tab button.mp-lb-mdkit-conflict-panel-tab-active: active preview tab button.mp-lb-mdkit-conflict-panel-action-row: action button row.mp-lb-mdkit-panel-secondary-action: secondary panel action button
The preview tabs also use aria-selected for state-aware styling.
Checkpoint History Panel
VersionHistoryPanel renders checkpoint history: a checkpoint list, selected
checkpoint preview, restore action, and empty/error states. The component and
CSS class names keep version-history for current API compatibility.
.mp-lb-mdkit-version-history-panel: root element.mp-lb-mdkit-version-history-header: panel header.mp-lb-mdkit-version-history-title: panel title.mp-lb-mdkit-version-history-subtitle: panel subtitle.mp-lb-mdkit-version-history-layout: list and preview layout.mp-lb-mdkit-version-history-list: checkpoint list.mp-lb-mdkit-version-history-item: checkpoint list item button.mp-lb-mdkit-version-history-item-active: selected checkpoint list item.mp-lb-mdkit-version-history-item-title: list item title.mp-lb-mdkit-version-history-item-meta: list item or selected checkpoint metadata.mp-lb-mdkit-version-history-preview: selected checkpoint preview area.mp-lb-mdkit-version-history-preview-header: preview header.mp-lb-mdkit-version-history-preview-title: preview title.mp-lb-mdkit-version-history-code: markdown preview code block.mp-lb-mdkit-version-history-empty: empty state text.mp-lb-mdkit-version-history-error: error state text.mp-lb-mdkit-version-history-meta: footer metadata.mp-lb-mdkit-panel-primary-action: primary panel action button
Shared Panel Actions
Conflict and checkpoint panels share generic action classes:
.mp-lb-mdkit-panel-primary-action: primary action button.mp-lb-mdkit-panel-secondary-action: secondary action button
CSS Variables
The package stylesheet defines variables on component roots so consumers can override broad styling without depending on internal element structure.
Editor Variables
Set these on .mp-lb-mdkit-markdown-editor, a custom className passed to
MdKitEditor, or the inline style prop:
--mp-lb-mdkit-background--mp-lb-mdkit-foreground--mp-lb-mdkit-muted--mp-lb-mdkit-muted-foreground--mp-lb-mdkit-border--mp-lb-mdkit-accent--mp-lb-mdkit-accent-foreground--mp-lb-mdkit-link--mp-lb-mdkit-font-family--mp-lb-mdkit-font-size--mp-lb-mdkit-line-height--mp-lb-mdkit-surface-padding--mp-lb-mdkit-block-gap--mp-lb-mdkit-list-item-gap--mp-lb-mdkit-heading-font-weight--mp-lb-mdkit-heading-1-size--mp-lb-mdkit-heading-2-size--mp-lb-mdkit-code-background--mp-lb-mdkit-code-radius--mp-lb-mdkit-code-block-radius--mp-lb-mdkit-code-font-family--mp-lb-mdkit-quote-border-color
Panel Variables
Set these on .mp-lb-mdkit-document-toolbar,
.mp-lb-mdkit-conflict-panel, .mp-lb-mdkit-version-history-panel, or a
wrapper around those components:
--mp-lb-mdkit-panel-background--mp-lb-mdkit-panel-surface--mp-lb-mdkit-panel-foreground--mp-lb-mdkit-panel-muted--mp-lb-mdkit-panel-muted-foreground--mp-lb-mdkit-panel-border--mp-lb-mdkit-panel-strong-border--mp-lb-mdkit-panel-danger--mp-lb-mdkit-panel-success--mp-lb-mdkit-panel-action-background--mp-lb-mdkit-panel-action-foreground
Theme Helpers
For app code, CSS variables are usually the simplest integration. The package also exports theme helpers when you want to store or generate a theme object:
import {
MdKitEditor,
createMdKitEditorThemeStyle,
darkMdKitEditorTheme,
} from "@mp-lb/mdkit";
const style = createMdKitEditorThemeStyle({
...darkMdKitEditorTheme,
fontFamily: "Inter, system-ui, sans-serif",
lineHeight: "1.75",
});
<MdKitEditor style={style} value={markdown} onChange={setMarkdown} />;Related exports are listed in the API reference.
Dark Mode
For class-based dark mode, scope variable overrides to your dark selector:
.my-markdown-editor {
--mp-lb-mdkit-background: #ffffff;
--mp-lb-mdkit-foreground: #172033;
--mp-lb-mdkit-muted: #eef1f4;
--mp-lb-mdkit-muted-foreground: #5b6472;
--mp-lb-mdkit-border: #d8dee8;
--mp-lb-mdkit-link: #4f46e5;
--mp-lb-mdkit-code-background: #eef1f4;
}
.dark .my-markdown-editor {
--mp-lb-mdkit-background: #0b1220;
--mp-lb-mdkit-foreground: #e5edf7;
--mp-lb-mdkit-muted: #172033;
--mp-lb-mdkit-muted-foreground: #94a3b8;
--mp-lb-mdkit-border: #314158;
--mp-lb-mdkit-link: #38bdf8;
--mp-lb-mdkit-code-background: #111827;
}Then apply the class normally:
<MdKitEditor
className="my-markdown-editor"
value={markdown}
onChange={setMarkdown}
/>You can also switch theme objects in React:
const style = createMdKitEditorThemeStyle(
isDark ? darkMdKitEditorTheme : defaultMdKitEditorTheme,
);
<MdKitEditor style={style} value={markdown} onChange={setMarkdown} />;What Not To Customize First
Prefer changing CSS variables before overriding internal selectors like
.mp-lb-mdkit-tiptap p or .mp-lb-mdkit-editor-surface. Direct selector overrides are still an
escape hatch, but they couple your app to mdkit's internal DOM.
Use MdKitThemeEditor for theme builders, documentation, and debug tooling. It
is not required for normal editor integration.