43

我使用 Sass 创建了一个全局样式表并将其放入public/style/styles.scss. 我只指定背景颜色。

在索引中,我添加了一个链接:<link rel="stylesheet" href="style/styles.css">

背景颜色不适用于 body 标签。在检查身体标签时,我可以看到背景颜色已被应用但被否决scaffolding.less:31

我做错了什么?

4

13 回答 13

44

从 CLI 的 beta.14 版本开始(使用 Angular 2.0 final),可以angular-cli.json在“styles”键下链接全局样式表。这是对相对于src/目录的文件的引用style.css,默认情况下。

利用这种方法,您可以:

  • 将全局样式复制到src/styles.css
  • 使用 CSS 导入将外部规则导入styles.css
  • apps[0].styles通过属性添加更多全局样式angular-cli.json

另请参阅的 wiki中的全局样式。angular-cli

于 2016-09-21T17:07:30.407 回答
17

以上答案都没有解释 Angular 的 CSS 系统中到底发生了什么,或者为什么您可能会看到级联问题。您可能会考虑将所有 CSS 从 Angular 编译器中移出并放入您自己的外部链接中。

在 Angular 项目中,当您将样式路径直接添加到“angular.json”(较新)或“angular-cli.json”(较旧)设置文件中时,Angular 会抓取所有这些 CSS 文件,将它们编译成 JavaScript 文件,然后在 HTML 文件的头部将它们作为嵌入样式吐出:

这个 angular.json 设置:

  "styles": [
    "src/styles.css",
  ],

转换为 HTML 并添加到JavaScript 在浏览器的 DOM 中创建的巨大嵌入标签中:<style>

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Project</title>

<style>
  .mystyle {background:blue;}/* everything in styles.css gets dumped in here! */
</style>

<body>
...

糟糕的 CSS 设计!只有当您使用浏览器并使用 F12 并查看浏览器内存中的实际 DOM 和 CSS 角度吐出时,您才能看到这一点。如果您使用组件样式,当这些组件通过 Angular 模块等加载到 DOM 时,也会发生同样的事情。它们被转储到第一个下的另一个嵌入式样式元素中。

我不是 100% 肯定 Angular 的人明白他们在做什么添加这样的嵌入式样式。如果在链接样式之后插入这些嵌入式样式系统,Angular 使用的这些嵌入式样式系统可以隐藏链接样式中的任何 CSS。

我不喜欢 Angular 的一件事是,如果您将 CSS IMPORT 标签放在“styles.css”文件中(例如引导),编译器也会抓取这些标签并将其吐出到这些嵌入的样式标签中. 传统上,将一个样式表导入另一个样式表用于控制级联顺序,因为导入的表在父页面中的其他样式之前插入。我们使用@import 来隐藏非常旧的浏览器不支持的样式,并通过这种方式按功能管理大型样式库。因为 Angular 现在忽略了所有这些并将所有这些 CSS 混杂在一起,所以在“index.html”文件的头部留下了一个巨大的嵌入式内联样式块,并且很难以这种方式控制级联顺序。

Angular 的样式系统也不支持使用此内联系统为网站或主题设置皮肤,也不支持页面之间链接样式的全局缓存,以节省带宽。正如上面提到的那样,您将样式表放在文件夹结构中的什么位置并不重要。如果它们在 angular.json 中被引用,它们都会以您无法控制的顺序编译到页面头部的这些嵌入式样式 blob。

出于这个原因,我建议您从“ANGULAR.JSON”中删除所有样式引用!然后将它们手动添加回您的“index.html”,如下所示:

<link href="styles/styles.css" rel="stylesheet" />

...然后通过删除样式数组路径列表中的样式条目然后将其粘贴回您的资产数组列表来更改 angular.json 设置文件,以便 Angular 知道将您的 CSS 文件夹和文件迁移到 dist 文件夹中的位置,如下所示:

        "assets": [
          "src/styles",
        ],
        "styles": [
        ],

您的 Angular 应用程序现在<link>在 index.html 文件中使用或使用外部 CSS 文件而不是<styles>嵌入的 CSS 样式。你仍然可以使用这个内部的或“嵌入的”Angular 管理的 CSS 系统。我不是 100% 反对它。在极少数情况下,嵌入式 CSS 非常适合支持离线网页。Angular 有一个很好的系统来控制和操作 CSS。但这并不是过去 20 年来大多数缓存系统中使用 CSS 的传统方式。使用“外部”或<link>CSS,您的主要样式现在可以在用户的​​“本机”浏览器缓存中存储更长的时间,从而节省带宽和浏览器中的渲染/绘制速度。

<link>CSS 让您可以完全控制您的网站样式、跨浏览器修复、皮肤等。您的前端设计师也可以控制它,并且更新独立于古怪的 polyfill、预处理、脚本依赖等。您现在也可以恢复完全控制您的级联顺序,如果您想完全控制它,这一点至关重要。

链接外部样式也比 Google Angular 损坏的 CSS 系统具有巨大的缓存优势,因为浏览器自然会在页面刷新或重新访问时缓存所有这些。自 1990 年代以来,我们一直以这种方式使用 CSS,所以我很困惑为什么 Google 会回到旧的内联样式系统。链接样式在管理和缓存 css 方面非常出色。我们还将版本控制查询字符串添加到链接的 CSS 文件 (/mystyles.css?v=1.2) 的末尾,以便您可以强制刷新等。再次执行此操作,删除 angular.json 文件中对 CSS 的所有引用并手动添加它们作为 index.html 文件头部的链接。

我确实认为您可以安全地使用 Angular 的模块化或基于组件的样式系统,只要您了解当您延迟加载或预加载 Angular 模块时,这些嵌入式样式元素确实会在每次新访问或刷新时从服务器推送到用户的脚本块。还要了解现代浏览器今天的工作方式与旧浏览器的工作方式不同......新浏览器不会在链接的样式之后解析嵌入的样式,而是遵守您将它们插入 HTML 页面头部的顺序。换句话说,今天,当 Angular 最终交付 HTML 时,你在页面中放置它们的顺序可能是不可预测的。如今,级联顺序主要由 HTML 设计器控制,而不是 W3C 建议。

我认为这是 Angular 模块化样式系统的主要目的……从设计师手中接管 CSS 的控制权,并希望他们不会注意到。但老实说,如果您使用外部工作表并遵循基本的级联规则,则没有必要。

于 2020-03-29T11:07:34.550 回答
7

还有一个添加外部 CSS 的解决方案,即将所有的 CSS 放在 assets/css 文件夹中,如下所示:

assets/css/style1.css
assets/css/style2.css
assets/css/style3.css

添加所有外部 CSS 后,您必须在全局 style.css(即 src/style.css)中导入它们的引用,如下所示:

@import 'assets/css/style1.css';
@import 'assets/css/style2.css';
@import 'assets/css/style3.css';

也不要忘记在 angular-cli.json 中包含全局 CSS,如下所示:

  "styles": [
    "styles.css",
  ],
于 2018-09-20T07:20:08.963 回答
6

2019 年 9 月:

大多数其他帖子都是旧的。

文件: \angular.json
键: 项目 > myProjectNameHere > 建筑师 > 构建 > 样式

"styles": [
    "src/styles.css",
    "node_modules/font-awesome/css/font-awesome.css",
    {
        "input": "./node_modules/bootstrap/dist/css/bootstrap.css"
    }
],

文件:src/styles.css

/* You can add global styles to this file, and also import other style files */
/* That is, have put css that is common for all pages in this file.  */

body {
  font-family: "Ubuntu", sans-serif;
}

有了以上两件事,css 就可以很好地应用于所有页面。

因此,如果您拥有 Angular 8 或更高版本,则无需进行任何新操作。
如果您有问题,那么您只需要清除缓存(或者,执行 Ctrl + Shift + R )

于 2019-09-15T14:01:14.463 回答
5

我知道这为时已晚,但随着事情不断变化。截至 2017 年 3 月 16 日

这对我来说适用于cli。

<link rel="stylesheet" href="src/styles.css">
于 2017-03-16T17:22:16.130 回答
4

虽然我认为@filoxo 的答案是记录在案的解决方案,但类似以下内容也适用于我,并且可能更清楚哪个组件需要它:

require('style!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss');

或者在使用更新版本的 Angular CLI 时:

require('style-loader!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss');

或者:

@Component({
    selector: 'my-component',
    styles: [require('style-loader!../../../node_modules/bootstrap/scss/bootstrap-reboot.scss')],
    styleUrls: ['./my.component.scss']
})

后者可能不允许;也许不应该同时提供stylesand styleUrls,因为我得到“一个对象文字在严格模式下不能有多个同名的属性”和“重复标识符'样式'”。

于 2016-12-14T12:50:29.347 回答
2

我遇到了同样的问题,并且在 cli 中甚至没有 sass/less 支持之前就找到了这个示例。我想cli(1.0.0-beta.5)的当前版本可能只编译组件级别的sass,甚至可能忽略/src文件夹中的.css。我设法将全局 *.css 放在 public/ 文件夹中并将其复制到 /dist,但无法从 /src 获得相同的行为,并且预处理器似乎默认没有编译。我想这可能是设计使然,恕我直言,这有点违反直觉。幸运的是,Angular cli 构建在 Broccoli 之上,学习如何使用 Broccoli 自定义构建可能非常值得花时间和精力,如下例所示:

这是我最终得到的 angular-cli-build.js 的副本。

'use strict';
/* global require, module */

var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
var compileSass = require('broccoli-sass');
var mergeTrees = require('broccoli-merge-trees');
var _ = require('lodash');
var glob = require('glob');

module.exports = function(defaults) {

  let sourceDir = 'src';
  let app = new Angular2App(defaults, {
      sourceDir: sourceDir,
      sassCompiler: {
        includePaths: [
          'src/style'
        ]
      },
      vendorNpmFiles: [
        'systemjs/dist/system-polyfills.js',
        'systemjs/dist/system.src.js',
        'zone.js/dist/*.js',
        'es6-shim/es6-shim.js',
        'reflect-metadata/*.js',
        'rxjs/**/*.js',
        '@angular/**/*.js'
      ]
    });
    let styles = mergeTrees(_.map(glob.sync('src/**/*.scss'), function(sassFile) {
        sassFile = sassFile.replace('src/', '');
        return compileSass(['src'], sassFile, sassFile.replace(/.scss$/, '.css'));
    }));
    return mergeTrees([app, styles], { overwrite: true });
};
于 2016-05-28T04:43:52.783 回答
2

嗨,在 Angular 4 中,我们可以在angular-cli.json 中引用的styles.css 中添加我们的全局样式

 "prefix": "app",
      "styles": [
        "styles.css"
      ],
      "scripts": [],

我们可以将我们所有的 css 导入到 styles.css 文件中

/* You can add global styles to this file, and also import other style files */
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
@import 'assets/css/test.css';
于 2018-04-18T04:23:11.093 回答
1

只需将 src/styles.css 重命名为 src/styles.scss

记得在 .angular-cli.json 中将styles.css 重命名为styles.scss。

于 2017-06-12T03:42:26.780 回答
0

我使用带有 SCSS 作为样式格式的 Angular v8.1.2,发现全局 syles.scss 不起作用。

在 angular.json 中,它是:

    "styles": [
      "src/styles.scss",
      "node_modules/bootstrap/dist/css/bootstrap.min.css"
    ],
    "scripts": [
      "node_modules/jquery/dist/jquery.min.js",
      "node_modules/bootstrap/dist/js/bootstrap.min.js"
    ]

谷歌搜索后,我从https://github.com/angular/angular-cli/issues/10855找到了原因:

仅当我们在 angular.json 的 projects.architect.build.options.styles 设置中有多个非空文件时,该问题才会重现。

我的解决方案:从样式数组中删除“node_modules/bootstrap/dist/css/bootstrap.min.css”条目,将“src/styles.scss”作为[]中的唯一文件,然后打开styles.scss ,并在内容顶部添加以下行:

@import "node_modules/bootstrap/dist/css/bootstrap.min";
于 2019-08-09T18:03:24.813 回答
0

我一直在使用以下策略(尽管我没有从 angular-cli 团队看到任何官方解决方案,所以可能有更好的方法):

如果我所有的 src 文件都在 src/app/... 中,我会在根 ./app 目录中放置一个 app.scss 文件。然后使用当前的构建配置自动编译为 css,所以我可以将它包含在我的 index.html 中:

<link rel="stylesheet" type="text/css" href="app/app.css">

如果您的文件结构由于某种原因与默认 CLI 文件结构不同,只需确保 app.scss 文件包含在您的主应用程序组件所在的同一目录中。我喜欢这种技术,因为这意味着我不必更改构建,从而减少将来更新项目的痛苦。

于 2016-06-08T04:58:26.843 回答
0

<app-root>对于您的应用程序(例如)范围之外的元素,<body>您可以使用其他人提供的解决方案。

如果元素在您的应用程序中,您也不能将其设为全局,而是在字符串中定义样式,然后将其导入到styles要使用这些样式的 Component 类装饰器的属性中。

这样,您将获得封装和重用。它只是带有将其写入字符串的缺点,这可能会限制您的编辑器对您的样式进行静态分析的能力。

AFAIK,角度 cli 不会编译两次。

例子:

const tableStyles = `
    table { color: red; }
`;
@Component({
    selector: 'app-overview',
    templateUrl: './overview.component.html',
    styleUrls: ['./overview.component.scss'],
    styles: [tableStyles] // <- here
})
export class OverviewComponent { ... }

如果您想将样式保存在适当的文件中,您可以将相同的逻辑应用于styleUrls属性。

例子:

@Component({
    selector: 'app-overview',
    templateUrl: './overview.component.html',
    styleUrls: [
        './overview.component.scss', 
        '../common/table-styles.scss' // <- here
    ]
})
export class OverviewComponent { ... }
于 2019-06-14T14:47:16.057 回答
-1

将 scss 添加到 angular-cli.json 的样式数组中。

于 2017-03-03T23:40:21.343 回答