docs: Component Styles guide for CLI (#19791)
This commit is contained in:
parent
1d19d61970
commit
567cc26b8e
|
@ -4,7 +4,8 @@
|
|||
"files": [
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.native.*"
|
||||
"!**/*.native.*",
|
||||
"!**/*.[1].*"
|
||||
],
|
||||
"tags": ["CSS"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
h1 {
|
||||
font-weight: normal;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { Component, HostBinding } from '@angular/core';
|
||||
import { Hero } from './hero';
|
||||
|
||||
// #docregion
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<h1>Tour of Heroes</h1>
|
||||
<app-hero-main [hero]="hero"></app-hero-main>
|
||||
`,
|
||||
styleUrls: ['./hero-app.component.css']
|
||||
})
|
||||
export class HeroAppComponent {
|
||||
// #enddocregion
|
||||
hero = new Hero(
|
||||
'Human Torch',
|
||||
['Mister Fantastic', 'Invisible Woman', 'Thing']
|
||||
);
|
||||
|
||||
@HostBinding('class') get themeClass() {
|
||||
return 'theme-light';
|
||||
}
|
||||
// #docregion
|
||||
}
|
||||
// #enddocregion
|
|
@ -6,7 +6,8 @@ import { Hero } from './hero';
|
|||
selector: 'app-root',
|
||||
template: `
|
||||
<h1>Tour of Heroes</h1>
|
||||
<app-hero-main [hero]=hero></app-hero-main>`,
|
||||
<app-hero-main [hero]="hero"></app-hero-main>
|
||||
`,
|
||||
styles: ['h1 { font-weight: normal; }']
|
||||
})
|
||||
export class HeroAppComponent {
|
||||
|
|
|
@ -9,23 +9,9 @@ with components, enabling a more modular design than regular stylesheets.
|
|||
|
||||
This page describes how to load and apply these component styles.
|
||||
|
||||
<!--
|
||||
|
||||
## Table Of Contents
|
||||
|
||||
* [Using component styles](guide/component-styles#using-component-styles)
|
||||
* [Special selectors](guide/component-styles#special-selectors)
|
||||
* [Loading styles into components](guide/component-styles#loading-styles)
|
||||
* [Controlling view encapsulation: native, emulated, and none](guide/component-styles#view-encapsulation)
|
||||
* [Appendix 1: Inspecting the CSS generated in emulated view encapsulation](guide/component-styles#inspect-generated-css)
|
||||
* [Appendix 2: Loading styles with relative URLs](guide/component-styles#relative-urls)
|
||||
|
||||
-->
|
||||
|
||||
You can run the <live-example></live-example> in Plunker and download the code from there.
|
||||
|
||||
|
||||
|
||||
## Using component styles
|
||||
|
||||
For every Angular component you write, you may define not only an HTML template,
|
||||
|
@ -36,34 +22,43 @@ One way to do this is to set the `styles` property in the component metadata.
|
|||
The `styles` property takes an array of strings that contain CSS code.
|
||||
Usually you give it one string, as in the following example:
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-app.component.ts" title="src/app/hero-app.component.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
## Style scope
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
The selectors you put into a component's styles apply only within the template
|
||||
of that component. The `h1` selector in the preceding example applies only to the `<h1>` tag
|
||||
in the template of `HeroAppComponent`. Any `<h1>` elements elsewhere in
|
||||
the application are unaffected.
|
||||
The styles specified in `@Component` metadata _apply only within the template of that component_.
|
||||
|
||||
This is a big improvement in modularity compared to how CSS traditionally works.
|
||||
</div>
|
||||
|
||||
They are _not inherited_ by any components nested within the template nor by any content projected into the component.
|
||||
|
||||
In this example, the `h1` style applies only to the `HeroAppComponent`,
|
||||
not to the nested `HeroMainComponent` nor to `<h1>` tags anywhere else in the application.
|
||||
|
||||
This scoping restriction is a ***styling modularity feature***.
|
||||
|
||||
* You can use the CSS class names and selectors that make the most sense in the context of each component.
|
||||
|
||||
|
||||
* Class names and selectors are local to the component and don't collide with
|
||||
classes and selectors used elsewhere in the application.
|
||||
|
||||
|
||||
* Changes to styles elsewhere in the application don't affect the component's styles.
|
||||
|
||||
|
||||
* You can co-locate the CSS code of each component with the TypeScript and HTML code of the component,
|
||||
which leads to a neat and tidy project structure.
|
||||
|
||||
|
||||
* You can change or remove component CSS code without searching through the
|
||||
whole application to find where else the code is used.
|
||||
|
||||
|
||||
{@a special-selectors}
|
||||
|
||||
|
||||
|
||||
## Special selectors
|
||||
|
||||
Component styles have a few special *selectors* from the world of shadow DOM style scoping
|
||||
|
@ -78,11 +73,8 @@ targeting elements *inside* the component's template).
|
|||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.css" region="host" title="src/app/hero-details.component.css" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
The `:host` selector is the only way to target the host element. You can't reach
|
||||
the host element from inside the component with other selectors because it's not part of the
|
||||
component's own template. The host element is in a parent component's template.
|
||||
|
@ -92,13 +84,9 @@ including another selector inside parentheses after `:host`.
|
|||
|
||||
The next example targets the host element again, but only when it also has the `active` CSS class.
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.css" region="hostfunction" title="src/app/hero-details.component.css" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
### :host-context
|
||||
|
||||
Sometimes it's useful to apply styles based on some condition *outside* of a component's view.
|
||||
|
@ -112,13 +100,9 @@ up to the document root. The `:host-context()` selector is useful when combined
|
|||
The following example applies a `background-color` style to all `<h2>` elements *inside* the component, only
|
||||
if some ancestor element has the CSS class `theme-light`.
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.css" region="hostcontext" title="src/app/hero-details.component.css" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
### (deprecated) `/deep/`, `>>>`, and `::ng-deep`
|
||||
|
||||
Component styles normally apply only to the HTML in the component's own template.
|
||||
|
@ -165,90 +149,80 @@ There are several ways to add styles to a component:
|
|||
|
||||
The scoping rules outlined earlier apply to each of these loading patterns.
|
||||
|
||||
### Styles in metadata
|
||||
### Styles in component metadata
|
||||
|
||||
You can add a `styles` array property to the `@Component` decorator.
|
||||
Each string in the array (usually just one string) defines the CSS.
|
||||
|
||||
Each string in the array defines some CSS for this component.
|
||||
|
||||
<code-example path="component-styles/src/app/hero-app.component.ts" title="src/app/hero-app.component.ts">
|
||||
|
||||
<code-example path="component-styles/src/app/hero-app.component.ts" title="src/app/hero-app.component.ts (CSS inline)">
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
|
||||
### Style URLs in metadata
|
||||
|
||||
You can load styles from external CSS files by adding a `styleUrls` attribute
|
||||
into a component's `@Component` decorator:
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.ts" region="styleurls" title="src/app/hero-details.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
|
||||
|
||||
The URL is relative to the *application root*, which is usually the
|
||||
location of the `index.html` web page that hosts the application.
|
||||
The style file URL is *not* relative to the component file.
|
||||
That's why the example URL begins `src/app/`.
|
||||
To specify a URL relative to the component file, see [Appendix 2](guide/component-styles#relative-urls).
|
||||
|
||||
Reminder: these styles apply _only to this component_.
|
||||
They are _not inherited_ by any components nested within the template nor by any content projected into the component.
|
||||
|
||||
</div>
|
||||
|
||||
The CLI defines an empty `styles` array when you create the component with the `--inline-styles` flag.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-app --inline-style
|
||||
</code-example>
|
||||
|
||||
### Style files in component metadata
|
||||
|
||||
You can load styles from external CSS files by adding a `styleUrls` property
|
||||
to a component's `@Component` decorator:
|
||||
|
||||
<code-tabs>
|
||||
<code-pane title="src/app/hero-app.component.ts (CSS in file)" path="component-styles/src/app/hero-app.component.1.ts"></code-pane>
|
||||
<code-pane title="src/app/hero-app.component.css" path="component-styles/src/app/hero-app.component.1.css"></code-pane>
|
||||
</code-tabs>
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
Reminder: the styles in the style file apply _only to this component_.
|
||||
They are _not inherited_ by any components nested within the template nor by any content projected into the component.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
If you use module bundlers like Webpack, you can also use the `styles` attribute
|
||||
to load styles from external files at build time. You could write:
|
||||
|
||||
`styles: [require('my.component.css')]`
|
||||
|
||||
Set the `styles` property, not the `styleUrls` property. The module
|
||||
bundler loads the CSS strings, not Angular.
|
||||
Angular sees the CSS strings only after the bundler loads them.
|
||||
To Angular, it's as if you wrote the `styles` array by hand.
|
||||
For information on loading CSS in this manner, refer to the module bundler's documentation.
|
||||
|
||||
You can specify more than one styles file or even a combination of `style` and `styleUrls`.
|
||||
|
||||
</div>
|
||||
|
||||
The CLI creates an empty styles file for you by default and references that file in the component's generated `styleUrls`.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate component hero-app
|
||||
</code-example>
|
||||
|
||||
### Template inline styles
|
||||
|
||||
You can embed styles directly into the HTML template by putting them
|
||||
You can embed CSS styles directly into the HTML template by putting them
|
||||
inside `<style>` tags.
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-controls.component.ts" region="inlinestyles" title="src/app/hero-controls.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
### Template link tags
|
||||
|
||||
You can also embed `<link>` tags into the component's HTML template.
|
||||
|
||||
As with `styleUrls`, the link tag's `href` URL is relative to the
|
||||
application root, not the component file.
|
||||
|
||||
You can also write `<link>` tags into the component's HTML template.
|
||||
|
||||
<code-example path="component-styles/src/app/hero-team.component.ts" region="stylelink" title="src/app/hero-team.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
<div class="alert is-critical">
|
||||
|
||||
The link tag's `href` URL must be relative to the
|
||||
_**application root**_, not relative to the component file.
|
||||
|
||||
When building with the CLI, be sure to include the linked style file among the assets to be copied to the server as described in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-asset-configuration).
|
||||
|
||||
</div>
|
||||
|
||||
### CSS @imports
|
||||
|
||||
|
@ -256,20 +230,39 @@ You can also import CSS files into the CSS files using the standard CSS `@import
|
|||
For details, see [`@import`](https://developer.mozilla.org/en/docs/Web/CSS/@import)
|
||||
on the [MDN](https://developer.mozilla.org) site.
|
||||
|
||||
|
||||
In this case, the URL is relative to the CSS file into which you're importing.
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/hero-details.component.css" region="import" title="src/app/hero-details.component.css (excerpt)">
|
||||
|
||||
</code-example>
|
||||
|
||||
### External and global style files
|
||||
|
||||
When building with the CLI, you must configure the `.angular-cli.json` to include _all external assets_, including external style files.
|
||||
|
||||
Register **global** style files in the `styles` section which, by default, is pre-configured with the global `styles.css` file.
|
||||
|
||||
See the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-global-styles) to learn more.
|
||||
|
||||
### Non-CSS style files
|
||||
|
||||
You can write style files in [sass](http://sass-lang.com/), [less](http://lesscss.org/), or [stylus](http://stylus-lang.com/) and specify those files in the `styleUrls` metadata, e.g.,
|
||||
|
||||
<code-example>
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
...
|
||||
</code-example>
|
||||
|
||||
The CLI build process runs the corresponding CSS pre-processors.
|
||||
|
||||
You can also configure the CLI to default to your preferred CSS pre-processer
|
||||
as explained in the [CLI documentation](https://github.com/angular/angular-cli/wiki/stories-css-preprocessors).
|
||||
|
||||
{@a view-encapsulation}
|
||||
|
||||
|
||||
|
||||
## View encapsulation
|
||||
|
||||
As discussed earlier, component CSS styles are encapsulated into the component's view and don't
|
||||
|
@ -296,25 +289,18 @@ Choose from the following modes:
|
|||
|
||||
To set the components encapsulation mode, use the `encapsulation` property in the component metadata:
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/quest-summary.component.ts" region="encapsulation.native" title="src/app/quest-summary.component.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
`Native` view encapsulation only works on browsers that have native support
|
||||
for shadow DOM (see [Shadow DOM v0](http://caniuse.com/#feat=shadowdom) on the
|
||||
[Can I use](http://caniuse.com) site). The support is still limited,
|
||||
which is why `Emulated` view encapsulation is the default mode and recommended
|
||||
in most cases.
|
||||
|
||||
|
||||
{@a inspect-generated-css}
|
||||
|
||||
|
||||
|
||||
## Appendix: Inspecting generated CSS
|
||||
## Inspecting generated CSS
|
||||
|
||||
When using emulated view encapsulation, Angular preprocesses
|
||||
all component styles so that they approximate the standard shadow CSS scoping rules.
|
||||
|
@ -323,7 +309,6 @@ In the DOM of a running Angular application with emulated view
|
|||
encapsulation enabled, each DOM element has some extra attributes
|
||||
attached to it:
|
||||
|
||||
|
||||
<code-example format="">
|
||||
<hero-details _nghost-pmm-5>
|
||||
<h2 _ngcontent-pmm-5>Mister Fantastic</h2>
|
||||
|
@ -334,8 +319,6 @@ attached to it:
|
|||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
There are two kinds of generated attributes:
|
||||
|
||||
* An element that would be a shadow DOM host in native encapsulation has a
|
||||
|
@ -347,7 +330,6 @@ The exact values of these attributes aren't important. They are automatically
|
|||
generated and you never refer to them in application code. But they are targeted
|
||||
by the generated component styles, which are in the `<head>` section of the DOM:
|
||||
|
||||
|
||||
<code-example format="">
|
||||
[_nghost-pmm-5] {
|
||||
display: block;
|
||||
|
@ -358,42 +340,8 @@ by the generated component styles, which are in the `<head>` section of the DOM:
|
|||
background-color: white;
|
||||
border: 1px solid #777;
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
These styles are post-processed so that each selector is augmented
|
||||
with `_nghost` or `_ngcontent` attribute selectors.
|
||||
These extra selectors enable the scoping rules described in this page.
|
||||
|
||||
|
||||
{@a relative-urls}
|
||||
|
||||
|
||||
|
||||
## Appendix: Loading with relative URLs
|
||||
|
||||
It's common practice to split a component's code, HTML, and CSS into three separate files in the same directory:
|
||||
|
||||
<code-example format="nocode">
|
||||
quest-summary.component.ts
|
||||
quest-summary.component.html
|
||||
quest-summary.component.css
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You include the template and CSS files by setting the `templateUrl` and `styleUrls` metadata properties respectively.
|
||||
Because these files are co-located with the component,
|
||||
it would be nice to refer to them by name without also having to specify a path back to the root of the application.
|
||||
|
||||
|
||||
You can use a relative URL by prefixing your filenames with `./`:
|
||||
|
||||
|
||||
<code-example path="component-styles/src/app/quest-summary.component.ts" title="src/app/quest-summary.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
|
Loading…
Reference in New Issue