- From: Raphael via GitHub <sysbot+gh@w3.org>
- Date: Mon, 10 Jun 2024 23:34:44 +0000
- To: public-css-archive@w3.org
raphaelokon has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-scoping] Proposal: Allow <slot> with LightDOM Web Components == CSS evolved extensively in the last four years and gained a lot of features such as `:has()`, `@container`, `@layer`, `@scope`, `CSS Anchor Positioning` and `@property()`, to name a few. These new CSS features change the concept of how we can write composable and high-distributable HTML with Web Components without always resolving to the highest power by utilizing ShadowDOM. In the rise of design systems, there is currently no way to combine the powers of both ModernCSS and `<slot>`. This proposal aims to solve this problem. ## Shadow Boundaries vs ModernCSS Using ShadowDOM leads to a lot of new CSS features being rendered useless; to provide an incomplete list of problems identified so far: 1. No containment queries (`@container`) across shadow boundaries of nested ShadowDOM Web components (was resolved via #5984 in spec but needs to be implemented across vendors). 2. `CSS Anchor Positioning` does not work cross shadow boundaries. 3. No use of `:has()` to style a parent depending on his slotted children (there is a [proposal for a `:has-slotted` selector](https://github.com/w3c/csswg-drafts/issues/6867)) 4. No import of global `@layer()`. Each shadow-root recreates the semantics of the layers. 5. No 100% CSS encapsulation as some styles pierce the shadow-boundary when slotting content into a shadow root. 6. Using complex selectors like `::part` that are limited in styling ShadowDOM content from *the outside*. 7. Using CSS Custom Properties as an API to control styles in ShadowDOM contents is limiting (compared to global CSS). 8. Additional: Constructable Stylesheets [cannot use `@import()`](https://github.com/WICG/construct-stylesheets/issues/119) 9. Additional: Adopted StyleSheets have a [bug in chromium](https://issues.chromium.org/issues/341327461) ## Solutions in the wild - StencilJS has experimental support for slots outside the ShadowDOM → https://ionic.io/blog/enhanced-support-for-slots-outside-of-shadow-dom - Lightning Design System allows users to create their components in multiple DOM flavors → https://developer.salesforce.com/docs/platform/lwc/guide/create-dom-intro.html - Keith Grant wrote a [SlottedElement to mimic <slots> in light DOM LitElements](https://gist.github.com/keithjgrant/bfb4c13806ec6cba643a9f2e86b2718c) There are articles in the web community that express the same sentiment about **slots** being the only-missing ShadowDOM feature. ## Proposed solution Since `<slot>`s are native to the ShadowDOM and cannot be polyfilled in the regular DOM (and style encapsulation can be achieved natively via modern CSS) the proposed solution is to let users use `<slot>` with LightDOM Web Components. A simplified example with slots inside a `<template>` without attaching a `shadowRoot` ```js class MyCard extends HTMLElement { constructor() { super(); let template = document.getElementById("card-template"); let templateContent = template.content; /** * Append the template content and somehow * reconstruct the flat-tree to allow slotting * and live content projection. * @TODO: This needs to be fleshed out. */ this.appendChild(templateContent.cloneNode(true); } } customElements.define("my-card", MyCard); ``` ```html <!-- The card template --> <template id="card-template"> <div class="card"> <div class="card-header"> <slot name="card-header"></slot> </div> <div class="card-content"> <slot></slot> </div> </div> </template> <!-- Using the web component --> <my-card> <h2 slot="card-header">My Card Header</h2> This is my regular card content. </my-card> ``` 1. No changes needed to the existing ShadowDOM specification (e.g. adding mechanisms to let global styles pierce the shadow boundary with `open-stylable` via #10176). 2. Developers can use all the new features such as `@layer` and `@scope` to provide a finer-grained CSS encapsulation. 3. Developers can keep their mental model writing CSS (as in trusting the cascade), and not use tightly coupled selectors `:host(parent-component) ::slotted(child-component) {…}` to establish connections between nested ShadowDOM Web Components. 4. Developers can hide the implementation details of their Custom Element and slot the content into the places needed without ShadowDOM. 5. Live content projection as with ShadowDOM. 6. Usage of `slotchange` event (optional). ## Open questions How can we signal that a LightDOM Web Component is using `<slot>`s without attaching another root node and appending the template to it? ## A path forward 1. Involve more people and gather more use-cases. 2. Gain deeper insights from the working group and verify the case. 3. Fleshing out how a flat-tree could look and be constructed. ## Addendum This is my first proposal that formed up after great talks with @bramus, @una, @fantasai, @andruud and @mirisuzanne at the CSSDay 2024. Happy for any comments/corrections/recommendations, cheers! Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10420 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 10 June 2024 23:34:45 UTC