Styling the Editor
Tiptap is designed to be unstyled by default, giving you complete control over the appearance of your editor. However, it does include some minimal base styles to ensure proper functionality.
Base Styles
Tiptap automatically injects minimal CSS styles required for the editor to function properly. These styles are injected by default but can be disabled.
.ProseMirror {
position : relative ;
word-wrap : break-word ;
white-space : pre-wrap ;
white-space : break-spaces;
-webkit-font-variant-ligatures : none ;
font-variant-ligatures : none ;
font-feature-settings : "liga" 0 ;
}
.ProseMirror [ contenteditable = "false" ] {
white-space : normal ;
}
.ProseMirror [ contenteditable = "false" ] [ contenteditable = "true" ] {
white-space : pre-wrap ;
}
.ProseMirror pre {
white-space : pre-wrap ;
}
.ProseMirror:focus {
outline : none ;
}
Source: packages/core/src/style.ts:1
Disabling CSS Injection
You can disable automatic CSS injection and provide your own styles.
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
const editor = new Editor ({
element: document . querySelector ( '.editor' ),
extensions: [ StarterKit ],
injectCSS: false , // Disable automatic CSS injection
})
Source: packages/core/src/Editor.ts:88
Editor Container Styling
Style the editor container to customize its appearance.
/* Basic editor styling */
.tiptap {
padding : 1 rem ;
min-height : 200 px ;
border : 1 px solid #e2e8f0 ;
border-radius : 0.5 rem ;
background : white ;
}
/* Focus state */
.tiptap:focus {
outline : none ;
border-color : #6366f1 ;
box-shadow : 0 0 0 3 px rgba ( 99 , 102 , 241 , 0.1 );
}
/* Caret color */
.tiptap {
caret-color : #6366f1 ;
}
Source: demos/src/Examples/Default/React/styles.scss:55
Content Styling
Style the content inside the editor.
/* Headings */
.tiptap h1 {
font-size : 2 rem ;
font-weight : 700 ;
line-height : 1.2 ;
margin : 1.5 rem 0 1 rem ;
}
.tiptap h2 {
font-size : 1.5 rem ;
font-weight : 600 ;
line-height : 1.3 ;
margin : 1.25 rem 0 0.75 rem ;
}
.tiptap h3 {
font-size : 1.25 rem ;
font-weight : 600 ;
line-height : 1.4 ;
margin : 1 rem 0 0.5 rem ;
}
/* Paragraphs */
.tiptap p {
margin : 0.75 rem 0 ;
line-height : 1.6 ;
}
/* Lists */
.tiptap ul ,
.tiptap ol {
padding-left : 1.5 rem ;
margin : 0.75 rem 0 ;
}
.tiptap li {
margin : 0.25 rem 0 ;
}
/* Blockquotes */
.tiptap blockquote {
border-left : 4 px solid #e2e8f0 ;
padding-left : 1 rem ;
margin : 1 rem 0 ;
color : #64748b ;
font-style : italic ;
}
/* Code */
.tiptap code {
background : #f1f5f9 ;
border-radius : 0.25 rem ;
padding : 0.125 rem 0.25 rem ;
font-family : 'JetBrains Mono' , monospace ;
font-size : 0.875 em ;
color : #e11d48 ;
}
.tiptap pre {
background : #1e293b ;
color : #e2e8f0 ;
border-radius : 0.5 rem ;
padding : 1 rem ;
margin : 1 rem 0 ;
overflow-x : auto ;
}
.tiptap pre code {
background : none ;
color : inherit ;
font-size : 0.875 rem ;
padding : 0 ;
}
/* Marks */
.tiptap strong {
font-weight : 700 ;
}
.tiptap em {
font-style : italic ;
}
.tiptap mark {
background : #fef08a ;
padding : 0.125 rem 0 ;
border-radius : 0.125 rem ;
}
.tiptap a {
color : #6366f1 ;
text-decoration : underline ;
cursor : pointer ;
}
.tiptap a :hover {
color : #4f46e5 ;
}
Placeholder Styling
Style placeholder text for empty content.
/* Using the Placeholder extension */
.tiptap p .is-editor-empty:first-child::before {
content : attr ( data-placeholder );
float : left ;
color : #adb5bd ;
pointer-events : none ;
height : 0 ;
}
/* Alternative approach */
.tiptap.is-empty::before {
content : 'Write something...' ;
color : #adb5bd ;
position : absolute ;
pointer-events : none ;
}
Selection Styling
Customize text selection appearance.
.tiptap ::selection {
background : rgba ( 99 , 102 , 241 , 0.2 );
}
.tiptap::-moz-selection {
background : rgba ( 99 , 102 , 241 , 0.2 );
}
Gap Cursor Styling
The gap cursor appears between block nodes.
.ProseMirror-gapcursor {
display : none ;
pointer-events : none ;
position : absolute ;
margin : 0 ;
}
.ProseMirror-gapcursor:after {
content : "" ;
display : block ;
position : absolute ;
top : -2 px ;
width : 20 px ;
border-top : 1 px solid #6366f1 ;
animation : ProseMirror-cursor-blink 1.1 s steps ( 2 , start ) infinite ;
}
@keyframes ProseMirror-cursor-blink {
to {
visibility : hidden ;
}
}
.ProseMirror-focused .ProseMirror-gapcursor {
display : block ;
}
Source: packages/core/src/style.ts:34
Dark Mode
Implement dark mode for your editor.
/* Dark mode container */
.dark .tiptap {
background : #1e293b ;
border-color : #334155 ;
color : #e2e8f0 ;
}
.dark .tiptap:focus {
border-color : #6366f1 ;
box-shadow : 0 0 0 3 px rgba ( 99 , 102 , 241 , 0.2 );
}
/* Dark mode content */
.dark .tiptap h1 ,
.dark .tiptap h2 ,
.dark .tiptap h3 {
color : #f1f5f9 ;
}
.dark .tiptap code {
background : #334155 ;
color : #fb7185 ;
}
.dark .tiptap pre {
background : #0f172a ;
}
.dark .tiptap blockquote {
border-left-color : #475569 ;
color : #94a3b8 ;
}
.dark .tiptap mark {
background : #854d0e ;
color : #fef08a ;
}
.dark .tiptap a {
color : #818cf8 ;
}
.dark .tiptap a :hover {
color : #a5b4fc ;
}
CSS Variables
Use CSS variables for consistent theming.
:root {
/* Colors */
--editor-bg : #ffffff ;
--editor-text : #1e293b ;
--editor-border : #e2e8f0 ;
--editor-focus : #6366f1 ;
--editor-placeholder : #94a3b8 ;
/* Spacing */
--editor-padding : 1 rem ;
--editor-border-radius : 0.5 rem ;
/* Typography */
--editor-font-family : -apple-system , BlinkMacSystemFont, 'Segoe UI' , sans-serif ;
--editor-font-size : 1 rem ;
--editor-line-height : 1.6 ;
}
.dark {
--editor-bg : #1e293b ;
--editor-text : #e2e8f0 ;
--editor-border : #334155 ;
--editor-focus : #6366f1 ;
--editor-placeholder : #64748b ;
}
.tiptap {
background : var ( --editor-bg );
color : var ( --editor-text );
border : 1 px solid var ( --editor-border );
border-radius : var ( --editor-border-radius );
padding : var ( --editor-padding );
font-family : var ( --editor-font-family );
font-size : var ( --editor-font-size );
line-height : var ( --editor-line-height );
}
.tiptap:focus {
border-color : var ( --editor-focus );
}
Source: demos/src/Examples/Default/React/styles.scss:1
Typography with Tailwind
Use Tailwind’s typography plugin for beautiful defaults.
Tailwind Typography
Tailwind Config
< template >
< EditorContent
:editor = "editor"
class = "prose prose-lg max-w-none focus:outline-none"
/>
</ template >
Custom Node Styling
Add custom classes to specific node types.
Custom Node Classes
Custom Node Styles
import { Node } from '@tiptap/core'
export const Paragraph = Node . create ({
name: 'paragraph' ,
addOptions () {
return {
HTMLAttributes: {
class: 'my-paragraph' ,
},
}
},
})
Responsive Design
Make your editor responsive.
/* Mobile */
@media ( max-width : 640 px ) {
.tiptap {
padding : 0.75 rem ;
font-size : 0.9375 rem ;
}
.tiptap h1 {
font-size : 1.5 rem ;
}
.tiptap h2 {
font-size : 1.25 rem ;
}
}
/* Tablet */
@media ( min-width : 641 px ) and ( max-width : 1024 px ) {
.tiptap {
padding : 1 rem ;
}
}
/* Desktop */
@media ( min-width : 1025 px ) {
.tiptap {
padding : 1.5 rem ;
max-width : 65 ch ;
margin : 0 auto ;
}
}
Print Styles
Optimize editor content for printing.
@media print {
.tiptap {
border : none ;
padding : 0 ;
}
.tiptap a {
text-decoration : underline ;
color : #000 ;
}
.tiptap a [ href ] :after {
content : " (" attr ( href ) ")" ;
}
.tiptap pre ,
.tiptap blockquote {
page-break-inside : avoid ;
}
}
Customize scrollbar appearance.
.tiptap::-webkit-scrollbar {
width : 14 px ;
height : 14 px ;
}
.tiptap::-webkit-scrollbar-track {
background-clip : padding-box ;
background-color : transparent ;
border : 4 px solid transparent ;
border-radius : 8 px ;
}
.tiptap::-webkit-scrollbar-thumb {
background-clip : padding-box ;
background-color : rgba ( 0 , 0 , 0 , 0 );
border : 4 px solid rgba ( 0 , 0 , 0 , 0 );
border-radius : 8 px ;
}
.tiptap:hover::-webkit-scrollbar-thumb {
background-color : rgba ( 0 , 0 , 0 , 0.1 );
}
.tiptap::-webkit-scrollbar-thumb:hover {
background-color : rgba ( 0 , 0 , 0 , 0.15 );
}
Source: demos/preview/style.css:101
Remember that Tiptap is headless, so you have complete control over styling. The examples above are just starting points.
Next Steps
TypeScript Add type safety to your editor
Collaborative Editing Enable real-time collaboration