我正在开发一个应用程序,用户可以通过拖放来构建网页。我们的用户可以删除的一些元素是Polymer2元素。
用户还可以在页面中添加自定义样式表,如果他们这样做,那里定义的样式应该会影响Polymer2元素的子项。
现在,我知道所有这些都违背了网络组件的行为方式,但我仍然想知道它是否可行。
我是Polymer的新手,并不太确定在哪个方向上看。我读过关于mixins,共享样式和自定义样式的内容,但似乎没有一个为我的用例提供有效的方法。
非常感谢任何帮助。
修改
到目前为止,我发现有一种解决方案可以正常运行但不理想,因为将来会弃用import
:
/parent-styles.html
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="parent-styles">
<link rel="import" type="css" href="ref_to_page_stylesheet.min.css">
</dom-module>
然后我可以导入此文件并使用<style include="parent-styles"></style>
。这至少允许从页面的样式表中设置Polymer元素的样式,但显然这个解决方案会在样式表名称或位置发生变化时立即中断,我对此并不满意。
答案 0 :(得分:1)
为Web组件设置样式有很多选项。一个组件 使用shadow DOM可以通过主页面设置样式,定义自己的样式, 或者为用户提供钩子(以CSS自定义属性的形式) 覆盖默认值。
要从外部设置组件<fancy-tabs>
的样式,您只需将其标记名称用作选择器:
fancy-tabs {
width: 350px;
}
外部样式总是胜过shadow DOM中定义的样式。但这只能让你到目前为止。如果你想为<fancy-tabs>
的内部设计样式怎么办?这是您必须使用自定义CSS属性创建样式挂钩的地方。
示例:
<!-- main page -->
<style>
fancy-tabs {
margin-bottom: 32px;
--fancy-tabs-bg: black;
}
</style>
<fancy-tabs background>...</fancy-tabs>
在<fancy-tabs>
的影子DOM中:
:host([background]) {
background: var(--fancy-tabs-bg, #9E9E9E);
border-radius: 10px;
padding: 10px;
}
在这种情况下,组件将使用黑色作为背景值,因为用户提供了它。否则,它将默认为#9E9E9E
。
答案 1 :(得分:0)
我自己制定了一些解决方案。正如我在问题中已经说过的那样,它有点违背了封装的Web组件哲学。它还依赖于将来会被弃用的链接标记。最糟糕的是,我还没有进行任何跨浏览器测试......所以:
小心使用!
您可以像下面这样使用下面的样式模块(导入后):
<style include="bb-shared-styles"></style>
<dom-module id="bb-shared-styles">
<template id="style-template">
<style id="stylesheet"></style>
</template>
<script>
((document) => {
const doc = (document._currentScript || document.currentScript).ownerDocument;
const domModule = doc.querySelector('#bb-shared-styles');
const template = doc.querySelector('#style-template');
const pageStyles = document.styleSheets;
const styles = template.content.querySelector('#stylesheet');
styles.type = 'text/css';
processStyleSheets();
function processStyleSheets () {
for (let index = 0; index < document.styleSheets.length; index++) {
const sheet = document.styleSheets[index];
if (sheet.href) {
// Prefer adding links to parsing CSS rules for better performance
appendLink(sheet.href);
} else {
const rules = sheet.rules || sheet.cssRules;
if (rules) {
// For inline styles
appendRules(rules);
}
}
}
}
function appendRules (rules) {
const len = rules.length;
for (let index = 0; index < len; index++) {
const rule = rules[index];
styles.appendChild(document.createTextNode(rule.cssText));
}
}
function appendLink (href) {
let link = document.createElement('link');
link.rel = 'import';
link.type = 'css';
link.href = href;
domModule.insertBefore(link, domModule.firstChild);
}
})(document);
</script>
</dom-module>