组件样式

2019-02-01  本文已影响0人  我不傻_cyy

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)模式是默认选项,并建议将其应用于大多数情况。

上一篇下一篇

猜你喜欢

热点阅读