angular使用标准的css来设置样式,所以可以把关于css的知识和技能直接用于angular程序中,例如样式表、选择器、规则以及媒体查询等。
angular会把组件样式绑定在组件上,这样可以实现比标准样式表更加模快化的设置。
放在组件样式中的选择器,只会应用在组件自身的模板中。
可以使用对每个组件最有意义的css类名和选择器
类名和选择器是仅属于组件内部的,它不会和应用中其他地方的类名和选择器出现冲突。
组件的样式不会因为别的地方修改了样式而被随意改变。
组件模板样式:
可以在组件的元数据中设置styles属性,styles属性可以接受一个包含css代码的字符串数组。
例如
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styles: ['h1 { font-weight: normal; }']
})
export class HeroAppComponent {
/* . . . */
}
在@Component的元数据中指定的样式只会对该组件的模板生效。它们既不会被模板中嵌套的组件继承,也不会被通过内容投影嵌进来的组件继承。
特殊的选择器
:host
使用:host伪类选择器,用来选择组件宿主元素中的元素(相对于组件模板内部的元素)。
:host{
display: block;
border:1px solid black;
}
因为宿主不是组件自身模板的一部分,而是父组件模板的一部分,所以:host是能以宿主元素为目标的唯一方式。
要把宿主样式作为条件,就要像函数一样把其他选择器放在:host后面的括号中。
:host(.active) { /*只有当宿主元素带有active类的时候才会生效*/
border-width: 3px;
}
:host-context
:host-context()伪类选择器在当前宿主元素的祖先节点中查找css类,直到文档的根节点为止。在与其他选择器组合使用时,她是非常有用的。
下面例子中,只有当某个祖先元素有css类theme-light时,我们才会把background-color样式应用到组件nebulous的所有<h2>元素中。
已废弃/deep/、>>>和::ng-deep
组件样式通常只会作用在组件自身的HTML上。
可以使用/deep/选择器来强制一个样式对各级子组件的视图也生效。它不但会作用于组件的子视图,也会作用于投影进来的内容(ng-content)
这个例子以所有的 <h3> 元素为目标,从宿主元素到当前元素再到 DOM 中的所有子元素:
:host /deep/ h3 {
font-style: italic;
}
/deep/组合器还有两个别名:>>>和::ng-deep
把样式加载进组件中
有几种方式把样式加入组件中:
1.设置styles或styleUrls元数据
2.内联在模板的HTML中
3.通过css文件导入
元数据中的样式
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styles: ['h1 { font-weight: normal; }']
})
export class HeroAppComponent {
/* . . . */
}
或者是把外部 CSS 文件添加到 `@Component的 styleUrls属性中来加载外部样式
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styleUrls: ['./hero-app.component.css']
})
export class HeroAppComponent {
/* . . . */
}
模板内联样式
@Component({
selector: 'app-hero-controls',
template: `
<style>
button {
background-color: white;
border: 1px solid #777;
}
</style>
<h3>Controls</h3>
<button (click)="activate()">Activate</button>
`
})
或者通过link标签引入样式
@Component({
selector: 'app-hero-team',
template: `
<!-- We must use a relative URL so that the AOT compiler can find the stylesheet -->
<link rel="stylesheet" href="../assets/hero-team.component.css">
<h3>Team</h3>
<ul>
<li *ngFor="let member of hero.team">
{{member}}
</li>
</ul>`
})
可以使用css的@imports语法来把css文件导入到css文件中
url是相对于正在导入的css文件的
/* The AOT compiler needs the `./` to show that this is local */
@import './hero-details-box.css';
需要在angular.json文件中配置全局样式文件。
可以使用sass、less、stylus来编写样式,并使用相应的扩展名(.scss、.less、.styl)来把它们指定到@Component.styleUrls元数据中。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
...
视图封装模式
通过在组件的元数据上设置视图封装模式,可以分别控制每个组件的封装模式,可选的封装模式如下:
1.ShadowDom模式使用浏览器原生的Shadow DOM实现来为组件的宿主元素附加一个Shadow DOM。组件的视图被附加到这个Shadow DOM中,组件的样式也被包含在这个Shadow DOM中。
2.Native视图包装模式使用浏览器原生的Shadow DOM的一个废弃实现。(没有样式能进来,组件样式出不去。不进不出)
3.Emulated模式通过预处理css代码来模拟Shadow DOM的行为,以达到把css样式局限在组件视图中的目的。(全局样式能进来,组件样式出不去。只进不出)
4.None意味着Angular不使用试图封装。Angular会把css添加到全局样式中,而不会应用前面讨论过的那些作用域规则、隔离和保护等。从本质上讲,这跟把组件的样式直接放进HTML是一样的。(能进能出)
通过组件元数据中的 encapsulation 属性来设置组件封装模式:
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native
ShadowDom模式只适用于提供了原生Shadow DOM支持的浏览器。它仍然受到很多限制,这个为什么仿真(Emulated)模式是默认选项,并建议将其应用于大多数情况。
网友评论