自定义组件样式

自定义组件样式

自定义Angular Material组件样式

Customizing Angular Material component styles

样式原则

Styling concepts

在自定义Angular Material组件样式的时,需要注意三个问题:

There are 3 questions to keep in mind while customizing the styles of Angular Material components:

  1. 你的样式封装了吗?
  2. 你的样式比默认样式更特殊吗?
  3. 这个组件是你的组件中的子组件,或者是存在于DOM中的某处吗?
  1. Are your styles encapsulated?
  2. Are your styles more specific than the defaults?
  3. Is the component a child of your component, or does it exist elsewhere in the DOM?

视图封装

View encapsulation

默认Angular组件样式只影响组件视图。这意味着你写的样式将会影响你的组件模板中的所有元素。它们不会影响你组件模板中的其它子组件内的元素。你可以通过Angular文档阅读更多关于视图封装的知识。你也可以在Angular博客中看一看Angular中的CSS状态查看更多。

By default, Angular component styles are scoped to affect the component’s view. This means that the styles you write will affect all the elements in your component template. They will not affect elements that are children of other components within your template. You can read more about view encapsulation in the Angular documentation. You may also wish to take a look at The State of CSS in Angular on the Angular blog.

选择器特征

Selector specificity

每个CSS声明都有一个基于使用的选择器类型和数量的特定级别。更特定的样式优先级高于不太特定的样式。Angular Material使用了最不特定的样式,这样使得其它组件可以轻易覆盖它们。你可以通过MDN web docs查看更多关于其特征与其计算方式。

Each CSS declaration has a level of specificity based on the type and number of selectors used. More specific styles will take precedence over less specific styles. Angular Material uses the least specific selectors possible for its components in order to make it easy to override them. You can read more about specificity and how it is calculated on the MDN web docs.

组件位置

Component location

一些Angular Material组件,特别是基于覆盖层的组件如MatDialog,MatSnackbar等,不能作为你的组件的子组件。它们经常被注入到DOM中。需要注意的是,因为即使使用了高特定性和阴影穿刺选择器,也无法定位那些不是你组件的直接子组件的元素。推荐使用全局样式来定位这些组件。

Some Angular Material components, specifically overlay-based ones like MatDialog, MatSnackbar, etc., do not exist as children of your component. Often they are injected elsewhere in the DOM. This is important to keep in mind, since even using high specificity and shadow-piercing selectors will not target elements that are not direct children of your component. Global styles are recommended for targeting such components.

覆盖组件样式

Styling overlay components

基于覆盖层的组件有一个panelClass属性(或者类似),可用于定位覆盖面板。例如,从对话框里移除padding:

Overlay-based components have a panelClass property (or similar) that can be used to target the overlay pane. For example, to remove the padding from a dialog:

// Add this to your global stylesheet after your theme setup
.myapp-no-padding-dialog .mat-dialog-container {
  padding: 0;
}
this.dialog.open(MyDialogComponent, {panelClass: 'myapp-no-padding-dialog'})

因为你已在全局样式表中添加样式,最佳实践方法是将其控制在适当的范围内。尝试在你的选择器前面增加前缀或者“custom”字段。同样需要注意到是mat-dialog-container的padding属性通过选择器默认其特定性为1。自定义样式的特定性为2,因此其优先级始终较高。

Since you are adding the styles to your global stylesheet, it is good practice to scope them appropriately. Try prefixing your selector with your app name or “custom”. Also note that the mat-dialog-container‘s padding is added by default via a selector with specificity of 1. The customizing styles have a specificity of 2, so they will always take precedence.

其它组件样式

Styling other components

如果你的组件视图封装已经打开(默认下是打开),你的组件样式只会影响模板中的顶层子元素。属于子组件的HTML元素不能通过你的组件样式来定位,不过也有以下几种方法:

If your component has view encapsulation turned on (default), your component styles will only affect the top level children in your template. HTML elements belonging to child components cannot be targeted by your component styles unless you do one of the following:

  • 在全局样式表中添加覆盖样式。将选择器的范围控制在只影响你需要的特定元素中。
  • 关闭组件中的视图封装功能。必须确保将你的样式控制在合理的范围内。否则,您可能会偶然地将目标锁定在应用程序中的其他组件。
  • 通过使用一个失效的阴影穿透的后代组合器,来强制样式应用于所有的子元素。可以在Angular文档中查看更多关于失效解决方法的信息。
  • Add the overriding style to you global stylesheet. Scope the selectors so that it only affects the specific elements you need it to.
  • Turn view encapsulation off on your component. If you do this, be sure to scope your styles appropriately, or else you may end up incidentally targeting other components elsewhere in your application.
  • Use a deprecated shadow-piercing descendant combinator to force styles to apply to all the child elements. Read more about this deprecated solution in the Angular documentation.

翻译部分版权归YahaCode团队所有。仅供学习研究之用,任何组织或个人不得私自以此用于任何形式的商业目的

发表评论