Skip to content

CSS Isolation

nuthrash edited this page Dec 27, 2022 · 6 revisions

Overview

The term "CSS Isolation" used by this topic is mean to isolate the content of HTML files against other parts of Obsidian, not mean the isolation CSS property or CSS isolation Property.

In the viewpoint of this plugin "HTML Reader", it has to load the content of a HTML file to a content view element of Obsidian. Without CSS Isolation, the CSS styles of HTML files would affect overall Obsidian, so you may see some font faces become ugly.

Possible Technologies

There are some technologies can apply CSS Isolation:

  1. Shadow DOM
  2. <iframe>
  3. CSS isolating packages

In my evaluating results inside Obsidian, I got:

  1. "Shadow DOM" solution would has less side effects.
  2. <iframe> solution is almost perfect but internal links cannot work normally.
  3. Cannot find any properly CSS isolating package to apply.

Therefore, I take "Shadow DOM" as the implementation technology as CSS isolation mechanism for Obsidian.

Shadow DOM

Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which you can attach any element, in the same way as the normal DOM.

There are some bits of shadow DOM terminology to be aware of:

  • Shadow host: The regular DOM node that the shadow DOM is attached to.
  • Shadow tree: The DOM tree inside the shadow DOM.
  • Shadow boundary: the place where the shadow DOM ends, and the regular DOM begins.
  • Shadow root: The root node of the shadow tree.
    --- from Using shadow DOM - Web Components | MDN

The code used in obsidian-html-plugin 1.0.6:

const contentDiv = this.contentEl.createDiv();
contentDiv.setAttribute( 'style', 'transform: scale(1);' );
const shadow = contentDiv.attachShadow( {mode: 'open'} );
shadow.addEventListener( 'click', sdFixAnchorClickHandler );
...

let domW = parserW.parseFromString( cleanHtmlText, 'text/html', { includeShadowRoots: true } );

...
shadow.appendChild( domW.documentElement );

The contentDiv.setAttribute( 'style', 'transform: scale(1);' ); would occupy isolating the CSS styles inside the Shadow Root. That means Shadow DOM cannot isolate all CSS styles very well.

The event handler sdFixAnchorClickHandler would fix the internal links while clicking them.

Side effects:

  1. Some CSS effects cannot work properly
    1. :target pseudo-class event would never be fired
Clone this wiki locally