import {Component} from 'angular2/core';
@Component({
selector: 'my-app',
template: '<div></div>',
styleUrls: [
'http://domain.com/external.css',
'app/local.css'
]
})
export class AppComponent {}
external.css
无法加载。有没有办法在Angular 2 Component中加载外部css?
答案 0 :(得分:84)
另见https://angular.io/docs/ts/latest/guide/component-styles.html
查看封装
要允许外部样式影响组件的内容,您可以更改视图封装(这是什么阻止样式到&#34;流入&#34;组件)。
@Component({
selector: 'some-component',
template: '<div></div>',
styleUrls: [
'http://example.com/external.css',
'app/local.css'
],
encapsulation: ViewEncapsulation.None,
})
export class SomeComponent {}
查看封装符合目的。更好的方法是将样式直接添加到它们应该影响的组件中。
每个组件设置ViewEncapsulation
,在某些情况下可能会派上用场。
&#34;阴影穿孔&#34;
您还可以使用阴影穿孔CSS组合器::ng-deep
(不推荐使用>>>
和/deep/
)来构建跨组件边界的选择器,例如
:host ::ng-deep .ng-invalid {
border-bottom: solid 3px red;
}
::slotted
,可以与`ViewEncapsulation.ShadowDom一起使用
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted 对当前组件中具有类ng-invalid
的所有标记设置样式,或者对任何具有红色下划线的后代设置样式,无论封装是None
还是Emulated
。这取决于浏览器支持/deep/
是否与Native
一起使用(据我所知,任何浏览器都不支持此功能)。
注意强>
阴影穿孔CSS组合器类似于shadow DOM规范中的组合,因为它们已经被弃用了很长一段时间。
使用默认 ViewEncapsulation.Emulated
使用Angulars自己的/deep/
和::shadow
实施,即使Chrome移除了原生支持,它们也能正常工作。
使用ViewEncapsulation.Native
Angular使用Chromes shadow DOM CSS组合器(只有Chrome支持它们AFAIK)。如果Chrome最终将其删除,那么他们也不会在Angular中工作(仅限ViewEncapsulation.Native
)。
全球风格
全局添加的样式(index.html
)不考虑组件边界。 Angular2不会重写此类样式,ViewEncapsulation.Emulated
不适用于它们。只有设置了ViewEncapsulation.Native
并且浏览器具有原生阴影DOM支持,全局样式才能进入。
答案 1 :(得分:11)
首先 - styles
/ styleUrls
只应用于任何直接影响模板元素样式的css规则。
您的external.css未应用于您的组件的原因是因为当您从styleUrls
或styles
在external.css中加载这些规则时,在编译时,angular2将附加一个唯一的组件标识符,如归属选择器的归属选择器。
例如,在您的external.css中,如果存在div.container { /*some rules*/ }
之类的规则,它将变为div.container[_ngcontent-cds-2] { /*some rules*/ }
。因此,无论你如何努力强迫你的规则成为优先规则,例如添加!important
标记,它不会起作用 - external.css中的所有选择器都被限制在属性选择器的一个级别,只有组件元素具有相同的属性。这就是angular2将样式限制为仅当前组件的方式。
这是我的解决方案 - 我将为所有js脚本添加外部资源服务,它将使用SystemJS
加载AMD或全局,对于所有css文件,它将使用普通javascript以创建<link>
元素并将其附加到<head>
元素。
以下是我需要考虑的代码:
loadCSS(url) {
// Create link
let link = document.createElement('link');
link.href = url;
link.rel = 'stylesheet';
link.type = 'text/css';
let head = document.getElementsByTagName('head')[0];
let links = head.getElementsByTagName('link');
let style = head.getElementsByTagName('style')[0];
// Check if the same style sheet has been loaded already.
let isLoaded = false;
for (var i = 0; i < links.length; i++) {
var node = links[i];
if (node.href.indexOf(link.href) > -1) {
isLoaded = true;
}
}
if (isLoaded) return;
head.insertBefore(link, style);
}
答案 2 :(得分:4)
这可能会迟到,希望这有助于其他人。要使用ViewEncapsulation,只需使用
import { ViewEncapsulation } from '@angular/core';
答案 3 :(得分:1)
此处已发布更好的方法:https://stackoverflow.com/a/36265072/5219412
您只需在组件的声明中添加:
@Component({
...
encapsulation: ViewEncapsulation.None,
})
如角度文档中所述:https://angular.io/guide/component-styles
希望它有所帮助。
答案 4 :(得分:-1)
这里有很多复杂的答案,但是我一直发现,如果我想创建一些影响多个组件的样式,则实际上是一种全局样式,因此将其添加到styles.css中。该css文件很特殊,因为它不使用样式封装,因此会影响每个组件。
从概念上讲,这对我来说似乎可以,只是您必须谨慎使用,否则styles.css太大。
丰富