Angular2中的高级样式特性

1、设置视图封装

    默认情况下,组件专用样式的实现方式是:编写应用于组件的CSS或less文件,使其针对一些特殊属性,让Angular将这些属性添加到组件模板的所有顶级元素中。如果使用浏览器的F12开发者工具检查DOM,将看到代码中的外部样式文件的内容已被重写,例如:

...
<style>
div[_ngcontent-c0] {
	backgroud-color: red;
}
</style>
...

    对选择器加以修改,使其能够匹配所有带有名为_ngcontent-c0的属性的div元素,但可能会在浏览器中看到不同名称,是因为该属性名称是由Angular动态生成的。
    为了保证style元素中的样式仅影响组件管理的HTML元素,对模板中的元素进行修改,这样它们就具有相同的动态生成的属性,如下所示:

...
<div _ngcontent-c0="" class="form-group">
	<input _ngcontent-c0="" class="form-control ng-invalid ng-untouched" ng-reflect-name="name" name="name"/>

</div>
...

    这被称为组件的视图封装(view encapsulation)行为,Angular正在做的是模拟被称为影子DOM(Shadow DOM)的特性:让DOM的各个部分彼此隔离,各自具有自己的范围,因此可以把JS、样式和模板应用到HTML文档的某一部分。Angular之所以模拟这种行为,是因为它仅由少量浏览器实现支持影子DOM特性,但有另外两个封装选项,可以使用@Component装饰器中的encapsulation属性来设置这些选项。

什么是影子DOM?
Web components 的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁。其中,Shadow DOM 接口是关键所在,它可以将一个隐藏的、独立的 DOM 附加到一个元素上。(MDN上有详细描述:Shadow DOM)

                                            ViewEncapsulation枚举中的值

名称描述
Emulated通过改写内容和样式来添加属性,从而模拟影子DOM。如果@Component装饰器中未指定encapsulation属性的值,那么这是默认行为
Native使用浏览器的影子DOM特性。这只有在浏览器实现影子DOM或者使用polyfill库时才有效
None将未修改的CSS样式添加到HTML文档的head节中,并让浏览器设法使用正常的CSS优先级规则来应用样式

    应该谨慎使用Native和None。浏览器对影子DOM特性的支持非常有限,只有在使用polyfill库(为其他浏览器提供兼容性)时,才能使用Native选项。
    选项None将组件定义的所有样式添加到HTML文档的head节中,并让浏览器设法应用它们。虽然这可以在所有浏览器中运行,但其结果是不可预测的,并且不同组件定义的样式之间没有隔离。为完整起见,使用默认的Emulated,它可以在Angular2支持的所有浏览器中运行而不需要polyfill库。

2、使用影子DOM CSS选择器

    使用影子DOM意味着存在一些边界,普通的CSS选择器不能跨越。下面列出的一些特殊的CSS选择器,当使用依赖影子DOM的样式(即使通过仿真实现)时,就会用到这些特殊的CSS选择器

名称描述
:host用于匹配组件的宿主元素
:host-context(classSelector)用于匹配属于特定CSS类成员的宿主元素的祖先
/deep/ 或 >>父组件使用此选择器来定义影响其子组件模板中元素的样式,只有当@Coponent装饰器的encapsulation属性被设置为emulated时,才应使用这个选择器
  • 选择宿主元素
        组件的宿主元素出现在其模板之外,这意味着其样式中选择器仅适用于宿主元素所包含的内部元素,而不适用于宿主元素本身。这个问题可通过使用与宿主元素相匹配的:host选择器来解决。
div {
	backgroud-color: red;
}
:host:hover {
	font-size: 20px;
}
  • 选择宿主元素的祖先
        :host-context选择器用于根据宿主元素的祖先(位于模板之外)的CSS类成员资格对组件模板中的元素进行样式化。这是相比:host更受限的选择器,不能用于指定除CSS类选择器以外的任何东西,而且不支持匹配标签类型、属性或任何其他选择器。
        只有在宿主元素的某个祖先元素是CSS类angular-app的成员时,选择器才将组件模板中input元素的backgroud-color属性设置为blue。
div {
	backgroud-color: red;
}
:host:hover {
	font-size: 20px;
}
:host-context(.angular-app) input {
	backgroud-color: blue;
}
  • 将样式推入子组件的模板中
        由组件定义的样式不会被自动应用到子组件模板的元素中。
        默认情况下,某些CSS样式属性(如font-style)会被继承,这意味着在父组件中设置这样的属性会影响子组件模板中的元素,这是因为浏览器会自动应用样式。
        而其他属性(如边框)默认情况下不会被继承,在父组件中设置这些属性对子组件模板没有影响,除非使用/deep/或>>选择器。样式选择器使用/deep/将样式推入子组件的模板中,这意味着所有div元素都被赋予一个边框。
...
@Component({
	selector: "app",
	templateUrl: "template.html",
	style: "/deep/ div { border:2px black solid; font-style: italic }"
})
...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~卷心菜~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值