使用HTML引入实现自定义元素样式的Polymer

3
我有一个自定义元素,使用的样式是通过HTML导入方式引入的。
从Chrome Stable(35.0.1916.114)和Canary(37.0.2008.2 canary)开始,这些样式不再应用于自定义元素内部定义的模板。 Safari(7.04)和Firefox Aurora [29.0a2(2014-02-11)]看起来很好。
Chrome是否存在回归问题?
例如,我的imports.html如下:
<link rel="stylesheet" href="/assets/stylesheets/libs/bootstrap.min.css" media="screen">
<script src="/assets/javascripts/libs/jquery.min.js" type="text/javascript"></script>
<script src="/assets/javascripts/libs/bootstrap.min.js" type="text/javascript"></script>

我的聚合物元素定义如下:

<link rel="import" href="imports.html">
<link rel="import" href="bower_components/polymer/polymer.html">

<polymer-element name="x-test">
<template>
  <select id="test">
    <option template repeat="{{ item in items }}" name="{{ item.id }}">
      {{ item.value }}
    </option>
  </select>
</template>
<script type="text/javascript">
  (function() {
    Polymer('x-test', {
      ... 
    });
  })();
</script>
</polymer-element>

使用的 Polymer 版本是:
"platform": "Polymer/platform#0.2.4",
"core-action-icons": "Polymer/core-action-icons#0.2.4"
"version": "0.2.4"
2个回答

3
Chrome 35正在使用真正的ShadowDOM,您正在看到ShadowDOM样式封装的效果。Polyfill版本之所以不同是因为它不完全支持ShadowDOM样式作用域。如果您希望boostrap样式应用于影子DOM中的元素,则需要在polymer-element模板中包含样式表。否则,重写规则以使用::shadow/deep/。更多信息:

您是否推荐在主页中使用单个Bootstrap导入(通过HTML导入),并使用::shadow/deep/,或定义单个自定义元素,其模板引入样式,并让浏览器对样式表进行去重的网络请求(因为这些样式可能嵌入多个自定义元素内)? - Rahul
使用一个共同的元素来引入样式并不是可行的解决方案,因为这些共同元素的样式本身是有作用域的。所以我想在每个需要它们的模板元素内部包含样式表会更容易一些。 - Rahul
@ebidel,::shadow和/deep/已经被弃用了,有什么替代选项吗? - Hasan A Yousef
CSS自定义属性:https://www.polymer-project.org/1.0/docs/devguide/styling.html - ebidel

1
由于在每个模板元素中包含样式表并不容易,因此我认为应该提供一个特殊的引导程序,在其选择器中添加“/deep/”。例如,对于“breadcrumb”,应将其更改为:
.breadcrumb {
  padding: 8px 15px;
  margin-bottom: 20px;
  list-style: none;
  background-color: #f5f5f5;
  border-radius: 4px;
}
.breadcrumb > li {
  display: inline-block;
}
.breadcrumb > li + li:before {
  padding: 0 5px;
  color: #ccc;
  content: "/\00a0";
}
.breadcrumb > .active {
  color: #999;
}

body /deep/ .breadcrumb {
  padding: 8px 15px;
  margin-bottom: 20px;
  list-style: none;
  background-color: #f5f5f5;
  border-radius: 4px;
}
body /deep/ .breadcrumb > li {
  display: inline-block;
}
body /deep/ .breadcrumb > li + li:before {
  padding: 0 5px;
  color: #ccc;
  content: "/\00a0";
}
body /deep/ .breadcrumb > .active {
  color: #999;
}

这并不容易,或者说应该很容易做到...

那么,@ebidel,有什么建议吗?


1
为什么在每个使用Bootstrap的元素中包含其CSS不容易?大量使用/deep/的CSS会破坏Polymer提供的样式封装,这使得开始变得有些棘手,但总体效果更好。相反,我认为最好拥有Bootstrap元素的适当Web组件实现。 - Peter Burns
1
在这种情况下,Bootstrap的CSS将被加载多次而不是一次。因此,如果所有自定义元素应具有相同的样式,则无需为每个自定义元素加载相同的CSS。否则,应单独加载CSS,而不使用Bootstrap的less不支持的hack /deep/。从ShadowDOM的设计来看,CSS不应支持样式的全局范围,但是那时候,我没有polymer进行测试。 - liudongmiao
包含Bootstrap的CSS(在每个自定义元素中)可以工作,但违反了DRY原则。不幸的是,选项似乎只有:a)使用/deep/并修改Bootstrap的样式或b)在每个元素声明中包含CSS。不确定是否还有其他解决方法。 - Rahul
@Rahul,是的,因为在每个元素的声明中包含css违反了DRY原则,即使polymer在layout.html中也包含了/deep/ css。所以我认为最好有一个/deep/版本的bootstrap。 - liudongmiao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接