-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make <link rel="stylesheet"> work inside shadow trees #4865
Comments
FYI: function resolveExternalStyleUrl(inst) {
const template = inst.querySelector('template');
const styles = template.content.querySelectorAll('link[rel="stylesheet"]');
Array.prototype.forEach.call(styles, (style) => {
style.setAttribute('href', Polymer.ResolveUrl.resolveUrl(style.getAttribute('href'), inst.assetpath));
});
}
// Then, call correctExternalStyleUrl(this); in register(id) |
While Native Issues Browsers typically block rendering on stylesheets that are in the document before it becomes interactive. This helps prevent FOUC. In order for a stylesheet in a shadowRoot to take advantage of this FOUC prevention, the shadowRoot must be created before the document becomes interactive. While this is possible, it's often not practical as element scripts are often loaded asynchronously. In this case, the element rendering will FOUC, which is typically not desirable. Further, even when the stylesheet is loaded, each rendered element that includes a Polyfill Issues In order to polyfill scoped styling, ShadyCSS must have access to the text of the stylesheets being applied to the element. Unfortunately, there is no way to get the raw text of a |
Thanks, @baocang for raising this important issue, and the thoughtful response from @sorvell. Using this approach to styling is a significant lowering of barrier to those of us who don't have time to build web components from scratch, but simply want to build on the great work of others by creating a low maintenance wrapper around third party framework agnostic api's. Especially during this time when @apply is being migrated to theme / parts. If whatever quirks there are with this approach can be worked out, I think it would result in a significant acceleration of web component adoption. At the risk of stating the obvious, it is slightly different syntax from what Polymer mentions is deprecated, which may throw some developers off. At a minimum, I recommend that the Polymer documentation be updated to acknowledge, at least, that there is this syntax which isn't deprecated, and the potential pitfalls of using it, and what the workarounds might be. To be honest, I'm not sure if it would be "correct" behavior for Polymer to perform url resolution of such stylesheet references automatically. Do the specs indicate the path is supposed to be evaluated relative to the [script] reference of the web component itself? If so, then I would second @baocang's proposal, in the sense that something is amiss (Chrome, maybe?). If the specs don't indicate this, it would still be useful, but maybe only if some custom polymer attribute is present, like "data-resolve"? I've used this technique, hopefully I won't grow to regret it, so I've been awaiting critical analysis from the Polymer team. The polyfill seems to work fine in browsers like IE11, but I'm not aware of any issues like styles "leaking out" from the shadow DOM. Is that what the issue is with polyfills? I can personally attest to the FOUC issue. But I find that it is fairly easy to rectify by not calling the third party rendering api until the load event finishes for the stylesheet, which seems par for what we can expect in today's brave new asynchronous world : const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', "text/css");
link.setAttribute('href', this._cssPath);
link.addEventListener('load', e => {
//do the render
});
this.shadowRoot.appendChild(link); I also am not seeing any outright evidence of the stylesheet being loaded twice. If you go here: https://www.webcomponents.org/element/bahrus/billboard-charts/demo/demo/index.html in Chrome (make sure to refresh so you have the latest version), only one instance of billboard.min.css shows up in the network tab, even with caching disabled, even though there are two instances of the chart. Are you referring to something more subtle? I do find that if I try to preload the style using the <link rel="preload" as="style" href=".../billboard.min.css"> tag, then it does end up getting downloaded twice. This strikes me as one of several preload related bugs in Chrome (sigh). Any idea of it's been logged? |
For the record, I have now seen some cases where the css loads repeatedly. I used this technique with a web component that appears multiple times in a grid that uses virtual rendering (ag-grid). The initial display of row data, I only see one request for the css file. But when I start scrolling, I start to see multiple requests, even if I uncheck the "disable caching" checkbox (i.e. allow for some caching). This seems like something Chrome should fix (reminds me of IE6 behavior, to be honest). |
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. |
This issue has been automatically closed after being marked stale. If you're still facing this problem with the above solution, please comment and we'll reopen! |
Has FOUC improved with the release of declarative Shadow DOM? |
Description
is now supported in a shadow tree, see: whatwg/html@43c5786, but polymer can not load it with correct path. this maybe a bug of chrome, but can fixed in
dom-module
now.Steps to Reproduce
polymer init polymer-2-application
nameddemo
<link rel="stylesheet" href="./demo-app.css">
polymer serve --open --open-path /
Expected Results
GET http://127.0.0.1:8003/src/demo-app/demo-app.css 200 OK
Actual Results
element-mixin.html:690 GET http://127.0.0.1:8003/demo-app.css 404 NOTFOUND
Browsers Affected
Versions
The text was updated successfully, but these errors were encountered: