Editor type scales for real: drop prosekit typography.css, fix selectors
Deploy / deploy (push) Successful in 1m16s

The earlier rem override never matched: editor.mount() turns the
.prosekit-editor div itself into the .ProseMirror root, so
'.prosekit-editor .ProseMirror p' selected nothing and prosekit
typography.css's fixed 16px kept winning. Verified by mounting the
editor standalone and reading the mount div's classes.

Rather than out-specificity a stylesheet we don't control, stop
loading it: prosekit's typography.css is optional px-based sugar. Our
own rem scale (now selected as direct children of .prosekit-editor)
plus UA em defaults for lists/blockquote/code is the whole editor
typography, all tracking the responsive root.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bendik Aagaard Lynghaug
2026-08-14 23:16:16 +02:00
co-authored by Claude Fable 5
parent 7b5d4dbf52
commit 5b3ffa62e8
2 changed files with 22 additions and 15 deletions
+4 -1
View File
@@ -285,8 +285,11 @@ function buildToolbar(editor) {
} }
export function mountEditor(container, hiddenInput, initial) { export function mountEditor(container, hiddenInput, initial) {
// Only the structural stylesheet (placeholder, lists, gap cursor).
// Deliberately NOT prosekit/basic/typography.css: it sizes content in
// fixed px, which fights the app's responsive root font-size. All
// editor typography lives in our own stylesheet, in rem.
ensureStylesheet('https://esm.sh/prosekit/basic/style.css') ensureStylesheet('https://esm.sh/prosekit/basic/style.css')
ensureStylesheet('https://esm.sh/prosekit/basic/typography.css')
const extension = union( const extension = union(
defineBasicExtension(), defineBasicExtension(),
+18 -14
View File
@@ -450,7 +450,8 @@ textarea:focus {
placeholder pseudo-element, which read far dimmer than the placeholder pseudo-element, which read far dimmer than the
native inputs next to it. */ native inputs next to it. */
::placeholder, ::placeholder,
.prosekit-editor .prosekit-placeholder::before { .prosekit-editor .prosekit-placeholder::before,
.prosekit-editor.prosekit-placeholder::before {
color: var(--ink-dim); color: var(--ink-dim);
opacity: 1; opacity: 1;
} }
@@ -508,57 +509,60 @@ textarea:focus {
box-shadow: 0 0 0 0.18rem var(--accent-soft); box-shadow: 0 0 0 0.18rem var(--accent-soft);
} }
/* ProseKit's typography.css (loaded from esm.sh at mount time) sets /* The editor's whole type scale, in rem. ProseKit's own typography.css
fixed px font sizes on .ProseMirror, so they ignore the responsive is deliberately not loaded (it sizes content in fixed px - see
root font-size. Re-state them in rem/em at the same proportions, mountEditor in prosekit-editor.js), so these rules are the only
with .prosekit-editor prefixed so these win on specificity. */ typography the editor gets, on top of UA defaults (em-based, they
.prosekit-editor .ProseMirror p { scale fine for lists/blockquote/code). NOTE: editor.mount() turns the
.prosekit-editor div itself into the .ProseMirror root, so content
elements are its direct children - no .ProseMirror in the selector. */
.prosekit-editor p {
font-size: 1rem; font-size: 1rem;
line-height: 1.5; line-height: 1.5;
margin: 0 0 0.6em; margin: 0 0 0.6em;
} }
.prosekit-editor .ProseMirror p:last-child { .prosekit-editor p:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
.prosekit-editor .ProseMirror h1 { .prosekit-editor h1 {
font-size: 2.5rem; font-size: 2.5rem;
line-height: 1.1; line-height: 1.1;
margin: 0.9em 0 0.1em; margin: 0.9em 0 0.1em;
} }
.prosekit-editor .ProseMirror h2 { .prosekit-editor h2 {
font-size: 1.875rem; font-size: 1.875rem;
line-height: 1.3; line-height: 1.3;
margin: 1.05em 0 0.13em; margin: 1.05em 0 0.13em;
} }
.prosekit-editor .ProseMirror h3 { .prosekit-editor h3 {
font-size: 1.5rem; font-size: 1.5rem;
line-height: 1.33; line-height: 1.33;
margin: 0.9em 0 0.04em; margin: 0.9em 0 0.04em;
} }
.prosekit-editor .ProseMirror h4 { .prosekit-editor h4 {
font-size: 1.25rem; font-size: 1.25rem;
line-height: 1.3; line-height: 1.3;
margin: 0.8em 0 0.05em; margin: 0.8em 0 0.05em;
} }
.prosekit-editor .ProseMirror h5 { .prosekit-editor h5 {
font-size: 1.125rem; font-size: 1.125rem;
line-height: 1.22; line-height: 1.22;
margin: 0.78em 0 0.06em; margin: 0.78em 0 0.06em;
} }
.prosekit-editor .ProseMirror h6 { .prosekit-editor h6 {
font-size: 1rem; font-size: 1rem;
line-height: 1.25; line-height: 1.25;
margin: 0.75em 0 0.06em; margin: 0.75em 0 0.06em;
} }
.prosekit-editor .ProseMirror :is(h1, h2, h3, h4, h5, h6):first-child { .prosekit-editor :is(h1, h2, h3, h4, h5, h6):first-child {
margin-top: 0; margin-top: 0;
} }