How to include custom material themes into components without duplicating mixins: mat-core and angular-material-theme
I came across the same problem, some of the discussion can be found here, and an insighful blog dealing with the issue here.
Point is that - as the theming guide correctly states - you should never import mixins @include mat-core()
and @include angular-material-theme($your-theme)
more than once in your entire project. But when you're working with SASS in your components, you often do want to refer to your theme variables and mat-color palette. It's tempting to import your entire theme into the component SASS, accidentally duplicating the material mixins.
The solution I ended up with I think is the one the theming guide describes
the definition of the theme object should be broken into its own file, separate from the inclusion of the mat-core and angular-material-theme mixins
but since it was initially unclear to me how to do it, here's a step by step for anyone stuck with the same:
- create a
assets/styles/partials
folder containing SASS partials
My folder looks like this:
assets/styles/partials/
_palette.scss // custom material palettes
_scaffolding.scss // general mixins
_theme.scss // <-- our theme definition
_variables.scss // global variables like fonts and colors
The _theme
partial contains the following:
// assets/styles/partials/_theme.scss
@import '~@angular/material/theming';
@import 'variables';
@import 'scaffolding';
@import 'palette';
$my-primary: mat-palette($mat-primary);
$my-accent: mat-palette($mat-accent);
$my-warn: mat-palette($mat-warn);
$my-theme: mat-light-theme($my-primary, $my-accent);
That's it. Do not include the material mixins mat-core
and angular-material-theme
in this file.
- create a global theme file
assets/styles/my-theme.scss
. It contains just three lines:
// assets/styles/my-theme.scss
@import 'partials/theme'; // our actual theme definition
@include mat-core(); // the required mat-core mixin
@include angular-material-theme($my-theme); // the declaration of our custom material theme
By doing this we have separated our theme partial, including all our custome palette, scaffolding and variables, from the file that includes mat-core and our custom material theme.
- In Angular.json, declare your my-theme file as global under styles
"styles": [ "src/assets/styles/my-theme.scss" ]
With this, our app uses our custom material theme throughout, but because the theme definition (in the theme
partial) is separate from the inclusion of material mixins (in my-theme
), we can safely include our theme
partial into any component without duplicating any css.
Optionally, you can simplify the import of our theme partial by adding the partials path to the stylePreprocessorOptions in Angular.json:
"build": {
(...)
"options": {
(...)
"stylePreprocessorOptions": {
"includePaths": [
"src/assets/styles/partials"
]
}
}
}
Simply @import 'theme'
in any component scss file and we have access to all our variables and the material theming functions such as mat-color :)
How should I apply a custom angular material theme?
Working example, pay attention to the 'mat-light-theme' line:
@import '~@angular/material/theming';
@include mat-core();
$app-primary: mat-palette($mat-indigo);
$app-accent: mat-palette($mat-amber, A200, A100, A400);
$app-warn: mat-palette($mat-red);
$app-theme: mat-light-theme($app-primary, $app-accent, $app-warn);
@include angular-material-theme($app-theme);
Custom theming Angular material
You're trying to @import
a SASS file in a CSS file. That won't work. I'd suggest changing styles.css
to styles.scss
and trying it again.
Angular Material Custom Component Theming
I described it in this stack overflow answer.
You should put the theme related variables and the theme creation in separate files:
styles/_variables.scss
- can be imported in all component scss files
- uses
@import '~@angular/material/theming';
to make material specific mixins available - contains typical theme variables like
$primary
,$accent
and$warn
- contains one or more
$theme
variables (e.g. viamat-light-theme($primary, $accent, $warn);
)
theme.scss
- should not be imported anywhere else
includes Angular Material core and theme
@import 'variables';
@include mat-core();
@include angular-material-theme($theme);
To easily import the styles/_variables.scss
into your component styles you have to add stylePreprocessorOptions
to the angular.json
file:
"styles": [
"src/styles.scss",
"src/theme.scss"
],
"stylePreprocessorOptions": {
"includePaths": [
"src/styles"
]
},
Now you can import you custom variables and theme variables in your component and use also material specific mixins like mat-color
:
@import 'variables';
$background: map-get($theme, background);
.custom-class-a {
background-color: mat-color($background, card);
color: mat-color($mat-green, 700);
}
Angular 9 / Material - Reuse of material theme variables in angular components style
You can do this in a different way:
There are something called 'partials'. You can create partials for various things and include/import them in your component.scss file and use them
Example:
At your root level, create a folder called styles. Inside styles, you can create multiple partials, one for variables, one for mixins, one for fonts etc.,
Partials start with an underscore for their file name such as _variables.scss, _mixins.scss, etc. The underscore will prevent the angular compiler from compiling everytime.
In '_variables.scss' file, you can create multiple global variables for colors, such as
$primary-color: #fff;
$secondary-color: #333; etc
In '_mixins.scss' you can create mixins such as
@mixin mixin-name() {
mixins functionality
}
In your component.scss file, simply import them and use it.
component.scss
@import '../styles/mixins';
@import '../styles/variables';
.component-class-name {
background-color: $primary-color;
color: $secondary-color;
}
Related Topics
CSS Transition Not Working for Percentage Height
Lessc Binary Not Available After Installing Less via Npm
Font-Feature-Settings: What Is the Correct Syntax
How to Create a CSS3 Gradient in Opera
Vertical Align Middle on an Inline-Block Anchor Tag
Chrome's Hidden CSS Scroll-Snap Threshold and How to Change It
How to Add CSS Files to a Custom Module in Odoo
Can't Stop CSS Animation Disappearing After Last Key Frame
Rstudio 0.98.1028 Add Background Image Only to Title Slide
Add Bullet Styling to Dd Element
Csp Style-Src: 'Unsafe-Inline' - Is It Worth It
Bind Angularjs Variables into CSS Syntax
Stretch a Background Image in IE8
Use CSS to Hide Contents on Print
CSS Media Type Print Using Background-Color in Chrome
Change Navbar Height in Bootstrap3
How to Stop a CSS Layout from Distorting When Zooming In/Out