From 5b3ffa62e87a7f1544967b9483e256f9c1dcc708 Mon Sep 17 00:00:00 2001 From: Bendik Aagaard Lynghaug Date: Fri, 14 Aug 2026 23:16:16 +0200 Subject: [PATCH] Editor type scales for real: drop prosekit typography.css, fix selectors 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 --- prosekit-editor.js | 5 ++++- style/main.css | 32 ++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/prosekit-editor.js b/prosekit-editor.js index 13b7380..bd0bebc 100644 --- a/prosekit-editor.js +++ b/prosekit-editor.js @@ -285,8 +285,11 @@ function buildToolbar(editor) { } 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/typography.css') const extension = union( defineBasicExtension(), diff --git a/style/main.css b/style/main.css index 240ca04..fd6c9f5 100644 --- a/style/main.css +++ b/style/main.css @@ -450,7 +450,8 @@ textarea:focus { placeholder pseudo-element, which read far dimmer than the native inputs next to it. */ ::placeholder, -.prosekit-editor .prosekit-placeholder::before { +.prosekit-editor .prosekit-placeholder::before, +.prosekit-editor.prosekit-placeholder::before { color: var(--ink-dim); opacity: 1; } @@ -508,57 +509,60 @@ textarea:focus { box-shadow: 0 0 0 0.18rem var(--accent-soft); } -/* ProseKit's typography.css (loaded from esm.sh at mount time) sets - fixed px font sizes on .ProseMirror, so they ignore the responsive - root font-size. Re-state them in rem/em at the same proportions, - with .prosekit-editor prefixed so these win on specificity. */ -.prosekit-editor .ProseMirror p { +/* The editor's whole type scale, in rem. ProseKit's own typography.css + is deliberately not loaded (it sizes content in fixed px - see + mountEditor in prosekit-editor.js), so these rules are the only + typography the editor gets, on top of UA defaults (em-based, they + 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; line-height: 1.5; margin: 0 0 0.6em; } -.prosekit-editor .ProseMirror p:last-child { +.prosekit-editor p:last-child { margin-bottom: 0; } -.prosekit-editor .ProseMirror h1 { +.prosekit-editor h1 { font-size: 2.5rem; line-height: 1.1; margin: 0.9em 0 0.1em; } -.prosekit-editor .ProseMirror h2 { +.prosekit-editor h2 { font-size: 1.875rem; line-height: 1.3; margin: 1.05em 0 0.13em; } -.prosekit-editor .ProseMirror h3 { +.prosekit-editor h3 { font-size: 1.5rem; line-height: 1.33; margin: 0.9em 0 0.04em; } -.prosekit-editor .ProseMirror h4 { +.prosekit-editor h4 { font-size: 1.25rem; line-height: 1.3; margin: 0.8em 0 0.05em; } -.prosekit-editor .ProseMirror h5 { +.prosekit-editor h5 { font-size: 1.125rem; line-height: 1.22; margin: 0.78em 0 0.06em; } -.prosekit-editor .ProseMirror h6 { +.prosekit-editor h6 { font-size: 1rem; line-height: 1.25; 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; }