应用程序样式设计是为用户提供出色体验的关键部分。在网络上,我们将级联样式表 (CSS) 作为强大的标准,供开发人员将应用程序的外观与其构造分开定义。
@Component({
selector: 'app-home',
imports: [],
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
默认情况下,在 Angular 中,当您将 CSS 直接附加到组件时,我们会将该 css 专门应用于该组件。此范围将其与应用程序的其余部分隔离。这个附加功能意味着有两种方法可以将 CSS 与 Angular 结合使用。
只要 CSS 存在,页面上加载的样式就会全局应用于该页面上的每个匹配元素。大多数开发人员每天都在使用这样的全局样式,并且社区开发了无数不同的方法来管理和组织这种样式,从简单的前缀到更复杂的系统(例如BEM和OOCS) 。
Angular 组件可以通过全局 CSS 设置样式,就像应用程序中的任何其他元素一样。只需将“<link>”元素放到您的页面上(通常在index.html 中)即可开始!然而,Angular 还为开发人员提供了更多选择来确定样式范围。
Angular 的组件模型使开发人员能够尽可能地独立构建。这也适用于样式,CSS 带来的意外副作用可能是不受欢迎的。
我们都曾遇到过这样的情况:看似无害的更改(例如将组件移动到不同的位置)会导致意外的级联更改。当范围不足的样式完全破坏页面布局时,就会发生这种情况。为了帮助避免类似的情况,Angular 将限制组件样式的范围,以便它们仅适用于该组件的模板内。
在 Angular 中使用组件范围 CSS 的开发人员将默认使用模拟模式进行此封装。在模拟模式下,我们生成随机属性并将其附加到每个实例化组件,然后创建使用这些生成的属性作为选择器的样式。
我们还支持Native模式,该模式将使用Shadow DOM创建额外的上下文并防止跨组件的样式泄漏。这适用于任何支持 Shadow DOM v1 的浏览器。原生模式在每个组件下创建一个影子根,这将完全隔离组件,甚至与全局定义的样式隔离(全局样式确实会通过模拟视图封装来刺穿组件)。
您可以选择的第三个也是最后一个封装是None ,这意味着您的所有 CSS 最终都会被全局应用。如果您想完全退出 Angular 的样式封装,则可以使用此选项。
但如果我想将这两个世界结合起来怎么办?我想编写组件范围的 CSS,它会影响组件本身以及我放入其中的任何子组件。
Angular 和浏览器历来提供了所谓的深度选择器。这也有其他几个名称,包括 >>>、/deep/ 或更官方的Shadow-Piercing 后代组合器。
深度选择器起源于 Blink 团队的努力。它允许开发人员跨影子根设计样式。它最终被弃用,因为它未能满足标准化、性能和开发人员体验的期望。
在 Angular 4.3 版本发布之前,SASS 等工具的更改和其他公告意味着我们现有的/deep/解释会产生冲突。为了让开发人员暂时摆脱这些外部驱动的重大更改,我们创建了::ng-deep来实现相同的功能。
由于我们希望保持模拟和本机样式封装的功能尽可能等效(希望未来浏览器标准化),因此在可以避免的情况下,我们不建议重新采用/deep/或::ng-deep 。
Dor Moshe 的一篇文章对::ng-deep 以及该功能的历史做了一些很好的介绍。
我们知道组件范围的 CSS 有合法的用例,您的样式会渗透到子组件中。您可以通过以下三种方法来实现这一目标:
社区反馈对我们非常重要。我们决定保持::ng-deep支持,直到自定义属性获得开发人员更广泛的接受、实施和验证。我们之所以能做到这一点,部分归功于社区的反馈和意见。感谢您一直以来的支持和反馈,我们将不断让 Angular 变得越来越好。
原文链接:https://blog.angular.dev/the-state-of-css-in-angular-4a52d4bd2700