如何确定动态注入到元素中的 Polymer @imports/stylesheets 的范围?
-
23-12-2019 - |
题
我目前正在为 Prism.js(语法荧光笔)开发 Polymer 元素。该元素已托管 这里 并且也在 GitHub 中 回购协议. 。我想做的是允许用户设置属性 theme
这决定了我们引入哪个主题文件。用户应该能够为每个元素设置不同的主题,并且这些样式的范围正确。
例如,如果您将元素配置为 <prism-js theme="tomorrow">
, ,当元素初始化时,我们读入 theme
价值并吸引 prism-tomorrow.css
通过注入它 @import
. 。如果我有另一个实例 <prism-js theme="coy">
, ,每个元素引入的主题不应发生冲突。
不幸的是,虽然 Canary 中的输出是正确的(每个元素的样式不冲突)。
在 Chrome 稳定版中,这些样式没有作用域并且相互破坏:
我想知道是否有可靠的方法来解决这个问题。
迄今为止,我已尝试:
- 注入我的风格
scoped
属性 - 这要么不受支持,要么不起作用 - 注入样式表的链接,该样式表附加到我的
shadowRoot
- 这也有同样的风格冲突问题 - 使用
shimStyling
- 同样的问题 - 根据 Polymer 文档,根据我的模板样式表进行工作:
var sheet = document.querySelector('style').sheet;
var hostRules = sheet.cssRules[0];
hostRules.cssText = '@import url("' + this.themepath + '");</style>';
或者,我想知道是否可以设置我的元素以便我可以更新 {{theme}}
在我的模板中 @import
如下:
<style>
:host { display: block; };
@import 'bower_components/prismjs/prism-{{theme}}.css';
</style>
不过,我不确定让它发挥作用是否也能解决我的范围界定问题。不幸的是,内联所有主题并不是一种选择。有任何想法吗?:)
解决方案
遗憾的是,像现在这样在 ShadowDOM polyfill 下实现按实例主题选择可能并不实际。
本机 ShadowRoot 可用的 CSS 范围很难进行 polyfill。如今,polyfill 做了很多技巧和翻译,以便提供 一些 范围界定,同时仍然保持高效。
然而,有两类范围界定问题存在问题:
- 每个实例范围(现在 CSS shim 按类型运行)
- 下限封装(元素的样式可以泄漏到其子树中的其他元素中)
考虑到这些限制,仍然有很多东西可以很好地工作,但是,特别是,像您想做的那样使用 CSS 并没有得到很好的支持。
目前正在研究通过 CSS shim 对(模拟)每个实例作用域的强制支持。如果有什么进展,我会尽力更新这个问题。