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

Implementation status

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 scroll to the internal link target anchors while clicking them. Because the internal links inside Obsidian would be added some prefix string before "#".

Side effects:

  1. Some CSS effects cannot work properly
    1. :target pseudo-class event would never be fired (the target anchor is scrolled into, so :target would never be fired!)

Some useful links

  1. Encapsulating Style and Structure with Shadow DOM by Caleb Williams
  2. Scoping CSS using Shadow DOM by Viduni Wickramarachchi
  3. Shadow DOM :獨立的Web組件 by 叡揚資訊

CSS isolating packages

I tried to evaluating some CSS isolating packages.

Cleanslate

Cleanslate site

Cleanslate is an extreme CSS reset stylesheet. It is used to reset the styling of an HTML element and all its children, back to default CSS values. It is composed exclusively of !important rules, which override all other types of rules.

It does not require any JavaScript – it’s just a CSS stylesheet. However, you may find it useful when used within JavaScript widgets, such as those created by Sqwidget.

This package reset many CSS styles to their default values, that means many CSS visual effects would different with original pages.

Clone this wiki locally