Skip to content

Commit c66ea05

Browse files
committed
docs: clarify points to address common issues
* Repeated reminders to only include mat-core once. * Note about including a theme file via styleUrls * Add section for theming only certain components * Move section on overlay theming after section for multiple themes
1 parent e0124bb commit c66ea05

File tree

1 file changed

+107
-32
lines changed

1 file changed

+107
-32
lines changed

guides/theming.md

Lines changed: 107 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -50,35 +50,27 @@ Finally, if your app's content **is not** placed inside of a `md-sidenav-contain
5050
need to add the `mat-app-background` class to your wrapper element (for example the `body`). This
5151
ensures that the proper theme background is applied to your page.
5252

53-
#### Theming overlay-based components
54-
Since certain components (e.g. `dialog`) are inside of a global overlay container, your theme may
55-
not be applied to them. In order to define the theme that will be used for overlay components, you
56-
have to specify it on the global `OverlayContainer` instance:
57-
58-
```ts
59-
import {OverlayContainer} from '@angular/material';
60-
61-
@NgModule({
62-
// misc config goes here
63-
})
64-
export class YourAppModule {
65-
constructor(overlayContainer: OverlayContainer) {
66-
overlayContainer.themeClass = 'your-theme';
67-
}
68-
}
69-
```
70-
7153
### Defining a custom theme
7254
When you want more customization than a pre-built theme offers, you can create your own theme file.
7355

74-
A theme file is a simple Sass file that defines your palettes and passes them to mixins that output
75-
the corresponding styles. A typical theme file will look something like this:
56+
A custom theme file does two thing:
57+
1. Imports the `mat-core()` sass mixin. This includes all common styles that are used by multiple
58+
components. **This should only be included once in your application.** If this mixin is included
59+
multiple times, your application will end up with multiple copies of these common styles.
60+
2. Defines a **theme** data structure as the composition of multiple palettes. This object can be
61+
created with either the `mat-light-theme` function or the `mat-dark-theme` function. The output of
62+
this function is then passed to the `angular-material-theme` mixin, which will output all of the
63+
corresponding styles for the theme.
64+
65+
66+
A typical theme file will look something like this:
7667
```scss
7768
@import '~@angular/material/theming';
7869
// Plus imports for other components in your app.
7970

80-
// Include the base styles for Angular Material core. We include this here so that you only
71+
// Include the common styles for Angular Material. We include this here so that you only
8172
// have to load a single css file for Angular Material in your app.
73+
// Be sure that you only ever include this mixin once!
8274
@include mat-core();
8375

8476
// Define the palettes for your theme using the Material Design palettes available in palette.scss
@@ -110,28 +102,111 @@ as gulp-sass or grunt-sass). The simplest approach is to use the `node-sass` CLI
110102
```
111103
node-sass src/unicorn-app-theme.scss dist/unicorn-app-theme.css
112104
```
113-
and then include the output file in your application.
105+
and then include the output file in your index.html.
114106

115107
The theme file can be concatenated and minified with the rest of the application's css.
116108

109+
Note that if you include the generated theme file in the `styleUrls` of an Angular component, those
110+
styles will be subject to that component's [view encapsultion](https://angular.io/docs/ts/latest/guide/component-styles.html#!#view-encapsulation).
111+
117112
#### Multiple themes
118-
You can extend the example above to define a second (or third or fourth) theme that is gated by
119-
some selector. For example, we could append the following to the example above to define a
120-
secondary dark theme:
113+
You can create multiple themes for you application by including the `angular-material-theme` mixin
114+
multiple times, where each inclusion is gated by an additional CSS class.
115+
116+
Remember to only ever include the `@mat-core` mixin only once; it should not be included for each
117+
theme.
118+
119+
##### Example of defining multiple themes:
121120
```scss
122-
.unicorn-dark-theme {
123-
$dark-primary: mat-palette($mat-blue-grey);
124-
$dark-accent: mat-palette($mat-amber, A200, A100, A400);
125-
$dark-warn: mat-palette($mat-deep-orange);
121+
@import '~@angular/material/theming';
122+
// Plus imports for other components in your app.
123+
124+
// Include the common styles for Angular Material. We include this here so that you only
125+
// have to load a single css file for Angular Material in your app.
126+
// **Be sure that you only ever include this mixin once!**
127+
@include mat-core();
128+
129+
// Define the default theme (same as the example above).
130+
$candy-app-primary: mat-palette($mat-indigo);
131+
$candy-app-accent: mat-palette($mat-pink, A200, A100, A400);
132+
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent);
133+
134+
// Include the default theme styles.
135+
@include angular-material-theme($candy-app-theme);
136+
126137

127-
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
138+
// Define a alternate dark theme.
139+
$dark-primary: mat-palette($mat-blue-grey);
140+
$dark-accent: mat-palette($mat-amber, A200, A100, A400);
141+
$dark-warn: mat-palette($mat-deep-orange);
142+
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
128143

144+
// Include the alternative theme styles inside of a block with a CSS class. You can make this
145+
// CSS class whatever you want. In this example, any component inside of an element with
146+
// `.unicorn-dark-theme` will be affected by this alternate dark theme instead of the default theme.
147+
.unicorn-dark-theme {
129148
@include angular-material-theme($dark-theme);
130149
}
131150
```
132151

133-
With this, any element inside of a parent with the `unicorn-dark-theme` class will use this
134-
dark theme.
152+
In the above example, any component inside of a parent with the `unicorn-dark-theme` class will use
153+
the dark theme, while other components will fall back to the default `$candy-app-theme`.
154+
155+
You can include as many themes as you like in this manner. You can also `@include` the
156+
`angular-material-theme` in separate files and then lazily load them based on an end-user
157+
interaction (how to lazily load the CSS assets will vary based on your application).
158+
159+
It's important to remember, however, that the `mat-core` mixin should only ever be included _once_.
160+
161+
##### Multiple themes and overlay-based components
162+
Since certain components (e.g. `dialog`) are inside of a global overlay container, the selector that
163+
determines the theme (such as the `.unicorn-dark-theme` example above), an additional step is needed
164+
to affect overlay-based components (menu, select, dialog, etc.).
165+
166+
To do this, can you specify a `themeClass` on the global overlay container. For the example above,
167+
this would look like:
168+
```ts
169+
import {OverlayContainer} from '@angular/material';
170+
171+
@NgModule({
172+
// ...
173+
})
174+
export class UnicornCandyAppModule {
175+
constructor(overlayContainer: OverlayContainer) {
176+
overlayContainer.themeClass = 'unicorn-dark-theme';
177+
}
178+
}
179+
```
180+
181+
The `themeClass` of the `OverlayContainer` can be changed at any time to change the active theme
182+
class.
183+
184+
#### Theming only certain components
185+
The `angular-material-theme` mixin will output styles for [all components in the library](https://github.com/angular/material2/blob/master/src/lib/core/theming/_all-theme.scss).
186+
If you are only using a subset of the components (or if you want to change the theme for specific
187+
components), you can include theme component-specific theme mixins. You also will need to include
188+
the `mat-core-theme` mixin as well, which contains theme-specific styles for common behaviors
189+
(such as ripples).
190+
191+
```scss
192+
@import '~@angular/material/theming';
193+
// Plus imports for other components in your app.
194+
195+
// Include the common styles for Angular Material. We include this here so that you only
196+
// have to load a single css file for Angular Material in your app.
197+
// **Be sure that you only ever include this mixin once!**
198+
@include mat-core();
199+
200+
// Define the theme.
201+
$candy-app-primary: mat-palette($mat-indigo);
202+
$candy-app-accent: mat-palette($mat-pink, A200, A100, A400);
203+
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent);
204+
205+
// Include the theme styles for only specified components.
206+
@include mat-core-theme($theme);
207+
@include mat-button-theme($theme);
208+
@include mat-checkbox-theme($theme);
209+
```
135210

136211
### Theming your own components
137212
For more details about theming your own components,

0 commit comments

Comments
 (0)