【问题标题】:Angular: Component styles do not cascade to sub-components?Angular:组件样式不会级联到子组件?
【发布时间】:2020-10-06 05:00:59
【问题描述】:

在我的 app.component.html 中,我有以下工作类作业。

<body>
  <span class="test">SHABOO</span>
  <div class="container">
    <router-outlet></router-outlet>
  </div>
</body>

在插座中,渲染了一个组件,它包含以下内容。

<span class="test">HAZAA</span>

我希望它获得与第一个相同的样式,但似乎该样式并没有级联到组件。这让我不确定我是否弄错了样式在 Angular 中父组件和子组件之间的行为方式。

我确保类的名称没有被覆盖(以排除碰撞的风险)。目前,我在每个组件中都放置了类似的 SCSS 代码块,这显然是一种不好的做法。

如果我@import "../app.component.scss",样式就会启动。但我的印象是,即使没有导入,样式也应该是级联的。

【问题讨论】:

    标签: css angular sass


    【解决方案1】:

    Angular 组件使用view encapsulation。这是设计使然,组件可跨应用程序重用。要将组件的样式视为全局,请将视图封装模式设置为none不推荐)。

    不要使用none,而是在Angular CLI styles section 中注册全局样式文件,该文件预先配置了styles.css 文件。

    组件 CSS 样式被封装到组件的视图中,不会影响应用程序的其余部分。

    要控制这种封装如何在每个组件 的基础上进行,您可以在组件元数据中设置视图封装模式。从以下模式中选择:

    • ShadowDom 视图封装使用浏览器的本机影子 DOM 实现(参见 MDN 站点上的 Shadow DOM)将影子 DOM 附加到组件的宿主元素,然后将组件视图放入该影子 DOM 中。组件的样式包含在 shadow DOM 中。

    • Native 视图封装使用了一个现已弃用的浏览器原生 shadow DOM 实现版本 - learn about the changes

    • Emulated 视图封装(默认)通过预处理(和重命名)CSS 代码来模拟影子 DOM 的行为,从而有效地将 CSS 限定在组件的视图中。详情请见Appendix 1

    • None 表示 Angular 没有视图封装。 Angular 将 CSS 添加到全局样式中。前面讨论的范围规则、隔离和保护不适用。这与将组件的样式粘贴到 HTML 中基本相同。

    要设置组件封装模式,请使用组件元数据中的 encapsulation 属性:

    src/app/quest-summary.component.ts

    // warning: few browsers support shadow DOM encapsulation at this time
    encapsulation: ViewEncapsulation.Native
    

    ShadowDom 视图封装仅适用于原生支持 shadow DOM 的浏览器(请参阅Can I use 站点上的Shadow DOM v1)。支持仍然有限,这就是为什么 Emulated 视图封装是默认模式并在大多数情况下推荐

    External and global style files

    使用 CLI 构建时,您必须配置 angular.json 以包含所有外部资产,包括外部样式文件。

    在样式部分注册全局样式文件,默认情况下,该部分预先配置了全局styles.css文件。

    请参阅CLI wiki 了解更多信息。

    【讨论】:

    • 所以,为了验证我的理解是否正确 - 你是说我所经历的行为是正确的,按照设计,我所指的级联不是我的产品混乱/想象力,但在 Angular 中默认情况下根本不活动。正确的?所以,如果我只是简单地导入全局 SCSS,一切都会变得很花哨。还是我错过了一些会回来咬我的东西?
    • @DonkeyBanana 正确,将样式隔离到组件的行为是设计使然。对于应在应用程序范围内应用的样式,请使用全局样式,例如默认顶级 styles.css(或 styles.scss)。
    • 通过使用全局样式,您的意思是我的个人 SCSS 文件顶部有一个 @import 声明,对吗?这是可以接受和合理的。
    • @DonkeyBanana 标准方法是在styles 配置选项中添加到angular.json 的文件中指定全局样式。 styles 配置选项定义为“要添加到项目全局上下文中的样式文件数组”。见Styles and scripts configuration。也可以根据需要@import样式。
    【解决方案2】:

    这就是 Angular 的工作原理。每个组件都用它的 CSS 分隔,即使它是父组件的子组件。他们不能继承他们的父 CSS。

    Haza span 组件是您的应用组件的子组件,但它是独立的组件。所以,你不能将那些 Shaboo 样式用于 Haza。

    解决方案:

    如果你想保持相同的 CSS,有多种方法。

    1. 推荐方式:

      a) 如果只针对单个类,则将该类复制到子组件中。

      b) 如果是针对大量类,请为它们创建一个 css 文件并将它们导入到父组件和子组件 css 中。 示例:

      @import '../span.css';

    2. 您可以将此 css 添加到 styles.css。然后你会在应用程序的任何地方得到它。如果很多地方都想要这种风格,你可以做到。

    3. 正如@Christopher Peisert 提到的,通过使用

      封装:ViewEncapsulation.Native child.component.ts 中 @component 装饰器的结尾。不推荐的方式

    【讨论】:

      【解决方案3】:

      全局 CSS 文件是那些在 angular.json 中列出的文件。其他所有CSS文件默认封装(可以去掉但不推荐)

      随着应用程序的增长,保持全局 CSS 井井有条很重要。我喜欢做的是创建一个全局样式文件夹,然后为我可能要更改的不同小部件添加新文件。由于删除 ::ng-deep 这些类型的更改必须在全局范围内完成。

      【讨论】:

        【解决方案4】:

        它就是这样工作的。如果您需要通用样式,请将其添加到全局 styles.scss 文件中。

        【讨论】:

          【解决方案5】:

          如果您想要一个全局样式,请将其放在全局文件 styles.css 或样式中。[您的 css 预处理器]

          见这个例子https://stackblitz.com/edit/angular-a5ntm6?file=src%2Fstyles.css

          我把测试类放在最后

          .test{
            color:red;
          }
          

          【讨论】:

            猜你喜欢
            • 2021-08-02
            • 2016-12-15
            • 1970-01-01
            • 2018-01-27
            • 2021-03-06
            • 2018-08-15
            • 2021-06-06
            • 2021-12-22
            • 1970-01-01
            相关资源
            最近更新 更多