Changes in CSS when WYSIWYG is released?

This is question for dev: How much [%] of current custom CSS code, will work when WYSIWYG is released?

1 Like

This is not really an answerable question in advance. If it were answerable, WYSIWYG would be released!

I wouldn’t expect much to change, per se, but having deep respect for the fact that Obsidian’s still in beta can only be healthy for us all.


I’ve been doing some work on a WYSIWYG plugin, and the main challenge with matching CSS (at least for the theme I use) is that there is some stuff in Obsidian’s built-in CSS that’s explicitly set differently between the two modes.

The specific differences I’ve encountered so far:

  • Headings have different sizes, line spacing, and font weight between edit and preview
  • Lists in edit are not indented, but in preview they are. (Dropping the indent in preview seems like a good way to resolve this, since the indent doesn’t seem to be doing anything useful; IMO a straight left edge is better for skimming and reading.)
  • Task lists are styled differently from non-task lists

The heading sizes I’ve worked around by adding this to the plugin’s css:

    // Fixes for inconsistent header formatting between preview and editing
    pre.HyperMD-header, .cm-header, .cm-header-1, .cm-header-2, .cm-header-3, .cm-header-4, .cm-header-5, .cm-header-6 { font-weight: 800; }
    pre.HyperMD-header-1 { font-size: 34px; line-height: 40px; }
    pre.HyperMD-header-2 { font-size: 26px; line-height: 32px; }
    pre.HyperMD-header-3 { font-size: 22px; line-height: 28px; }
    pre.HyperMD-header-4 { font-size: 20px; line-height: 24px; }
    pre.HyperMD-header-5 { font-size: 18px; line-height: 24px; }
    pre.HyperMD-header-6 { font-size: 18px; line-height: 24px; color: var(--text-muted); }

This works around the inconsistent line heights and font sizes/weights between edit and preview. It’s also a good indication of what a custom theme would need to do in order to make sure both edit and preview were styled, as far as headers go.

For the task list thing, my plugin is going to have to hook into the codemirror instance to allow a change in styling. But that’s not a huge deal since I already need to do that to get multi-line selections to not look/act weird, and to (someday) make clickable checkboxes, links, etc. (I’ve already got checkboxes that look pretty much like checkboxes, it’s just that clicking them doesn’t do anything currently.)

Currently though, I’m actively using my plugin and at least for basic text, headings, and lists, its edit mode now looks very similar to preview. Toggling in and out of preview mostly affects vertical spacing (since blank lines are collapsed in preview), the indentation of lists, and the presence of bullets on task lists.

I’ve got a long ways to go before it’s anything like Typora, but since Obsidian’s editor is based on HyperMD, there’s a lot more possible in principle.


I am not sure exactly how you are trying to achieve this. However some users have done sone work to make the regular editor more WYSWYG. Clutter free edit mode.

And also themes:

Looking forward to see what you come up with!

It’s a combination of CSS and CodeMirror augmentations. One of the flaws with a CSS-only approach is that the current CodeMirror settings used by Obsidian, the “active line” class does not appear on a line if text is selected. So my plugin sets cm.setOption("styleActiveLine", {nonEmpty: true}); so that the active line class is still applicable when text is selected on a line.

Another thing that JS augmentation allows is to add things like “clicking on a checkbox toggles the task state” – I just added that this morning, it was only about 5 lines since I’m just calling the editor:toggle-checklist-status command to do it. (It was ironically much more complicated to simulate the appearance of a Chrome checkbox using just CSS; with that part done, implementing the click handler itself was a breeze.)

At this point I’ve gotten it to where there’s not an immediately obvious difference between edit and preview modes: you have to look at some fairly fine details to tell, at least for things that aren’t huge (like a mermaid block or an embed). Getting links to behave more like they do in say, Typora or HyperMD is going to be a fair amount of work though.

That is, though, my overall goal, is to get it to where it can replace Typora in most instances, at least for my personal use cases. It’s one of those things where the last 20% takes 80% of the time, though, especially for fine polish. Right now, for example, the “click on simulated checkbox to toggle to-do state” thing is a little janky because the when the click event fires, the CodeMirror state isn’t fully settled, so I’m using a setTimeout to work around it. I really need to capture clicks the way Obsidian is doing it (mousedown+mouseup) and/or hook into it more at the CodeMirror level than the DOM level. It’s particularly challenging when the click is causing a change in focus from one pane to another, since that’s tripping onfocus and thus setActiveLeaf()… so Obsidian’s state isn’t settled yet, either, at that point. Probably I need to check if the codemirror belongs to the active leaf and is focused, and if not, do that before issuing the command.

So yeah… a LOT of fine details to this thing, to get it anywhere near Typora in terms of UX and reliability. But what I’ve got now is already leagues ahead of any of the CSS-only approaches to this, at least from my POV.

By the way, speaking of CSS issues, I notice that the .markdown-preview-view is setting left and right padding of 10% and making it !important. This seems kind of weird and wrong because it’s using up a lot of screen real estate for margins that don’t seem to be needed. (Source mode, after all, doesn’t have the same.) Currently, my plugin works around it with:

.markdown-preview-view {
    padding-left: 40px !important;
    padding-right: 40px!important;
    ul { padding-inline-start: 20px; }
    ul.contains-task-list { padding-inline-start: 25px; }

This makes the preview have similar margins to the source mode, and left-aligns bullets and checkboxes for a less ragged reading edge.

1 Like