diff --git a/proposals/Declarative-Shadow-DOM.md b/proposals/Declarative-Shadow-DOM.md new file mode 100644 index 00000000..de929559 --- /dev/null +++ b/proposals/Declarative-Shadow-DOM.md @@ -0,0 +1,317 @@ +Declarative Shadow DOM +----- +> Proposed by Tomek Wytrębowicz, Starcounter on Feb 6th, 2018 + +## Abstract + +[Shadow DOM](https://www.w3.org/TR/shadow-dom/) provides a way to build a document as a composition of separated DOM trees. It allows to encapsulate HTML, scope styles, ids and hide pieces of markup from external use. However, so far there is no way to achieve that using pure HTML. JavaScript was required to **imperatively** call `element.attachShadow`, even though there may be no scripting involved in the trees themselves. This document states a proposal for **declarative way** to create shadow roots. To allow to encapsulate HTML within HTML, support non-scripting environments, simplify markup, unify developer experience. + +It aggregates the ideas from: +https://discourse.wicg.io/t/declarative-shadow-dom/1904 +https://github.com/whatwg/dom/issues/510 + + +## Use cases +### Self-sufficient HTML +Shadow DOM encapsulation allows creating cleaner, more modular HTML documents that have scoped `id`s, hidden `div`-soup, etc. However, an author skilled in HTML, working in environment that supports it, who wants to prepare a document with no interaction or scripting involved, have to learn and enable JavaScript just to support HTML feature. + +An HTML document author should be able to use the effects of Shadow DOM on HTML by using only HTML. + +### Scoped CSS +There was demand expressed by the community for scoped styles. The separate spec for it was stopped due to scoping mechanism delivered by Shadow DOM. But again, author skilled in CSS and HTML cannot use those features without adding many lines of JavaScript. Sometimes, it's not even possible to run JS due to environment or policy limitations. + +HTML & CSS developer, should be able to use CSS scoping using only HTML and CSS + +### Non-scripting environments (bots, SEO, disabled-JS) +Since Shadow DOM is available, authors have to pay a significant price for using Shadow DOM. It was making the content non-accessible for web crawlers, web scrapers, other bots, or in various environments that does not support JavaScript. Therefore for publishers that cares about linked open data and SEO, this is simply a reason not to use Shadow DOM at all. + +We need a way to use Shadow DOM, in a JS-free environment. + +### Server-side rendering +Generating static HTML from JavaScript on the server (so-called server-side rendering) is a technique used to improve the perceived performance, SEO, and the support for non-scripting environments. The result of it is the entire content being available to the web client before loading of any scripts, Custom Elements definitions, upgrading elements, fetching cascade of XHRs, etc. + +We need a way to be able to serve shadow roots, of native and custom elements, in a static HTML document and let them upgrade progressively. + +### Performance + +Using declarative Shadow DOM to create a shadow root allows avoiding the performance overhead of crossing the boundary between HTML and JavaScript. + +## Background/Current shape + +- Libraries (like Polymer) provide a declarative way to provide Shadow DOM for a custom element, +- [Declarative Custom Elements proposal](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Declarative-Custom-Elements-Strawman.md) provides the declarative way to define the shadow root for a custom element. + + The above two solutions provides valuable sugar layer on top of existing API, but in case of Custom Elements the scripting is often needed anyway - to define the behavior. + + There are, however, times when an author likes to provide a shadow root for an element (native `div`, or custom one) just to create the DOM tree, without any need for custom behaviors or scripting. Defining a custom element every time you need a shadow root is an overhead. + +- Most search engines are blind to Shadow DOM, + +- In some HTML authoring environments, such as IDEs, content management systems, it is not possible to use nor support Shadow DOM, due to complexity of JavaScript to scripting policy limitations. + +- Dev tools, tutorials, spec samples already show the declarative convention like: + ```html + + #shadowroot +

Shadow Content

+

Light content

+
+ ``` + However, developers are not able to use that syntax by themselves. It is confusing, that you cannot just copy and paste the example from the spec into your HTML document to see it working. + +## Proposed Solution + +### Syntax +To create a shadow root declaratively, the `` element should be used. +```html + + +

Shadow Content

+ +
+

Light content

+
+``` + + - The content of `` should be exactly what imperative Shadow DOM allows. + - The element should have `mode` attribute set to either `"open"` or `"closed"` + > Note: If we agree on a default mode for `attachShadow`, we should remove this constraint. + +### Behavior + +Once parsed should create shadow root in parent element - **host**, and append its own content into there. ([test](https://gist.github.com/tomalec/a20af4eee86640defdc7aeccccc78c1c#file-declarative-shadow-dom-test-html-L8-L12)) + +- `host.innerHTML = 'shadow DOMlight DOM'` gets parsed and processed as declarative Shadow DOM and light DOM. ([test](https://gist.github.com/tomalec/a20af4eee86640defdc7aeccccc78c1c#file-declarative-shadow-dom-test-html-L14-L19)) + +- Once parsed `` must not appear in `host.childNodes`, nor `host.children` list. ([test](https://gist.github.com/tomalec/a20af4eee86640defdc7aeccccc78c1c#file-declarative-shadow-dom-test-html-L21-L27)) + + To access shadow root imperatively, use already settled API `host.shadowRoot`, `host.shadowRoot.childNodes`. + +- Once parsed `` must not appear in `host.innerHTML`. + + To access shadow root imperatively, use already settled API `host.shadowRoot`, `host.shadowRoot.innerHTML`. + + +- `host.appendChild(document.createElement('shadowroot'))` does append `HTMLUnknownElement`. ([test](https://gist.github.com/tomalec/a20af4eee86640defdc7aeccccc78c1c#file-declarative-shadow-dom-test-html-L29-L39)) + + To imperatively attach a shadow root, use `host.attachShadow`. + > Note, consider throwing an error + +- It should have `mode` attribute equal to `open` or `closed`, otherwise it is processed as `HTMLUnknownElement` ([test](https://gist.github.com/tomalec/a20af4eee86640defdc7aeccccc78c1c#file-declarative-shadow-dom-test-html-L41-L67)) + +- Scripts in `` are processed: + + >Note, Given the `