【问题标题】:Why does changing css for a single component affect all other components?为什么更改单个组件的 css 会影响所有其他组件?
【发布时间】:2020-08-31 00:20:34
【问题描述】:

目标:让 CSS 只影响其所在的组件,而不影响其他组件。我只想影响我的下拉菜单,而不是其他文本输入字段:

背景/问题:我理解为什么它会影响同一页面上的多个项目(mat-form-field 的)。但不明白为什么它会影响其他页面。我调查了它,但仍然不确定。

我尝试了什么: 例如,我原来有:

::ng-deep .mat-form-field-appearance-outline .mat-form-field-flex {
    height: 40px !important
}

::ng-deep .mat-form-field-infix {
    padding-top: 1px !important;
    padding-bottom: 2px !important;
}

但它会影响页面上所有表单域的间距,所以我将其编辑为

::ng-deep .mat-form-field-appearance-outline .mat-form-field-flex {
    height: 40px !important
}

::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
    padding-top: 1px !important;
    padding-bottom: 2px !important;
}

其他未更改的 CSS:

.title-container {
    position: relative;
    margin-top: 8px;
}

.language-field {
    position: absolute;
    right: 0;
    top: 0;
    margin-top: -16px;
    width: 115px;
    height: 20px !important;
}

这解决了这个问题,但我仍然奇怪的是,更改 login.component.css 上的某些内容会影响站点中的所有其他页面,例如 profile.component.css

这里是 login.component 的关联 HTML:

<div class="title-container">
    <mat-card-title class="text-center">
        Please Sign In
    </mat-card-title>

    <form [formGroup]="_siteForm">
        <mat-form-field class="language-field" appearance="outline">
            <mat-select (selectionChange)="changeSite($event)" [value]="languages[i].value">
                <mat-option *ngFor="let language of languages" [value]="language.value">
                    {{language.viewValue}}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </form>        
</div> 

当我对此进行研究时: 我发现一些 SO 文章(例如 Angular 2+ : Component style keeps affecting other components)提到使用封装:ViewEncapsulation 但是,在浏览该站点时,我没有看到它在任何地方使用,但是在不同的组件上都有 css,它们都提到了 mat-form-field 但具有不同的值。这似乎表明不需要封装。 在常规的 HTML 中,我没有遇到过这些问题,但对它在 Angular 中的工作方式感到困惑。这是否与 Angular 成为 SPA 有关?

【问题讨论】:

  • 请注意,::ng-deepdeprecated,但没有关于何时将其删除的时间表。

标签: css angular


【解决方案1】:

我认为这是你的 ::ng-deep,删除它。

然后使用特定的类名并在该组件 css 文件中声明它。 例如在 home.component.css

.mat-form-field-flex {
    height: 40px !important
}

【讨论】:

  • 感谢 Lilly_Code。听起来你在说: .myclass { padding-top: 1px !important; padding-bottom: 2px !important;但是html仍然会保留
  • 我尝试将这些添加到 html 中的“语言字段”类中,但没有成功。我还尝试删除 ngdeep 但随后删除了样式(盒子在一个奇怪的地方,奇怪的大小)
【解决方案2】:

如果没有带有该 CSS 的代码 sn-p,很难理解您要在此处显示的内容。

但是,如果它破坏了所有组件默认具有的 Angular 视图封装,我几乎可以肯定这是因为您使用的是 !important 选择器,这些实际上应该只在最罕见的情况下使用 - https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

这样做的原因是因为使用 !important 会破坏 Angular 对 encapsulate 它的组件使用的 css 特异性。

Css 的特殊性就是这样工作的。

内联样式值 1000 分

身份证价值100分

课程值 10 分

元素值 1pt

!important 本质上值得无限点,它总是优先。

div&gt;p&gt;.className = 12 分
div&gt;p&gt;#classname = 102 分

这意味着

中的任何样式

div&gt;p&gt;#classname

将优先于任何样式

div&gt;p&gt;.classname

我不会在这里详细介绍 Angular 如何使用这种技术实现封装,如果你感兴趣的话,这里有一篇好文章 - https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html

【讨论】:

    最近更新 更多