add option to disable / opt-out of Shadow DOM to support global CSS libraries
See original GitHub issueFeature Request
Problem to solve
As great as Shadow DOM in Web Components is, for projects supporting and / or trying to migrate away from global CSS, they may need to keep global CSS in lieu of encapsulating all styles.
How this relates to this project is that the custom element provided by this library has it enabled, which means for all apps using this library but also trying to use libraries like Bootstrap or Font Awesome (like me 😅 ), this library will block out all those global styles within the route. (which is the expected behavior, naturally).
(screenshots and more details at the end 👇 )
Possible implementation
Lit provides a way to disable this from the LitElement
base class by using createRenderRoot
export class MyComponent extends LitElement {
...
createRenderRoot() {
return this;
}
}
Thinking of this from a user of this library’s perspective, I think it would look something like this
<lit-route
path="/"
component="as-route-home"
shadow="false"
.resolve="${() => import('/routes/home/home.js')}">
</lit-route>
Not specifically sure how that would be implemented within this project though on the fly though?
export class LitRoute extends LitElement {
...
static get properties() {
return {
shadow: {
type: Boolean
}
};
}
constructor() {
super();
this.shadow = true;
}
createRenderRoot() {
return this.shadow ? this.shadowRoot : this;
}
}
(Lit doesn’t specify what the default would be, I am assuming it is this.shadowRoot
, but i can certainly ask on their issue tracker if it helps)
Alternatives considered
Technically there is one way to work around this, which is to just literally inline / include all that global CSS into the Shadow DOM for each custom element. Unfortunately, this means you’ll basically be duplicating all that CSS over and over, which is terrible for bundle size and user experience.
Additional context
You can check out my work in progress in this PR trying to to make all the CSS global, with the following observations:
- As a test, the header includes an icon from Font Awesome, which displays when the header is NOT in a route, and is not visible when the header IS in a route. Thus
<LitRoute>
is acting as a Shadow “boundary” preventing FA and Bootstrap from getting through to all the child components. - The difference in bundle size when not needing to inline all the duplicate global CSS is pretty significant: going from 1.3 MB to 289 KB!
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (2 by maintainers)
Top GitHub Comments
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Analyzing this a bit further I see a complication with a use where you provide the route content through the
slot
, since that is not available in light dom.I think the only way to fulfill this feature without loosing other will be with an option in the
lit-route
element