Feature Request
Custom theme should be able to override most colors/styles used in material theme (assuming they are SCSS variables). This override should be possible at time of theme generation and not by overriding CSS after the fact. The variables are already there but some are marked as !default while others (that could also be) are not.
Certain variables ($light-primary-text, entire $mat-grey palette) are used directly in SCSS and not via theme setup ($mat-light-theme-foreground). These should have !default flag to allow customization at theme generation time.
To cleanly override some of these colors, I currently make a copy of _theming.scss and update this file manually so I don't have to override CSS after it has been generated; thus maintain brittle CSS that might change in future material updates.
This suggestion simply implies adding !default to a few more variables, I realize current behavior is likely deliberate to prevent users from shooting themselves in the foot, but this also has a side effect; if someone is going to override these variables it's on them, no different than rest of styling.
There seems to be a slight syntax variant in how to override maps that's different than standard variables i.e.
$grays: () !default;
$grays: map-merge(( "100": $gray-100, "200": $gray-200, "300": $gray-300, etc... ), $grays);
Would be nice to add !default also to maps like $mat-light-theme-foreground to be able to overwrite or extend them. For example, I would like to add other keys in order to have options that make semantically more sense (e.g. right now the border color of checkboxes gets its color by the key secondary-text in the aforementioned map, which seems a bit weird to me).
Edit: But you are right, you can actually override or extend maps by merging them before executing @include angular-material-theme($theme);.
For example:
@import "~@angular/material/_theming.scss";
/* … */
$custom-extension: (
"border-color": #9fa2a3,
"border-color-hover": #626466,
"some-other-stuff": red
);
// Here we extend the $mat-light-theme-foreground map imported by the first @import at the top.
$mat-light-theme-foreground: map-merge(
$mat-light-theme-foreground,
$custom-extension
);
/* After the extension, you define $theme with the `mat-light-theme` function (not shown here), and use it. */
@include angular-material-theme($theme);
// In your custom code you can now use the extended $mat-light-theme-foreground map.
@include custom-mixin-that-includes-custom-components($theme);
See #12248, #13008, #4003, #3152, #1509, #5216
Copying from one of the earlier issues:
We don't consider the variables to be part of the public API for Angular Material at this time. The issue with overriding them is that it would force sass compilation to happen downstream, disallow the components from being able to use styleUrls, and generally make the getting-started workflow more complicated.
Ultimately css custom properties is the way we want to address this, but supporting IE11 makes this not feasible presently.
Thanks for linking to these issues @jelbourn but there is clearly a desire for this from the community, it seems too easily dismissed, especially since level of effort here appears reasonable (unless I'm missing something). We're already compiling downstream when theming with SCSS what harm can there be from exposing the variables? CSS variables are not some magic bullet, SCSS variables will make sense for years to come. It's disappointing that the material team takes such a restricted stance on styling while being extremely strong on the component architecture. Again, apologies if I don't understand the details well enough, but it doesn't strike me as anyone is trying to solve this.
The fundamental issue here is twofold.
Issue number one is that making this possible would make the Sass surface a public API. The existing public API surface area for Angular CDK + Material is already huge; the more we open this up, the harder it becomes to make any changes at all.
Issue number two is the build graph. Any given component uses styleUrls to reference a CSS file. When we publish the library, that CSS file has to exist, so the compilation has to happen before publishing. Angular doesn't have a way to hot-swap style files that would enable leaf applications to affect the CSS that's associated with the component.
CSS variables really do make this problem much easier to address. Because we're so close to using them, it's ultimately going to be the most effective use of the team's time to revisit the theming system just once.
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
Thanks for linking to these issues @jelbourn but there is clearly a desire for this from the community, it seems too easily dismissed, especially since level of effort here appears reasonable (unless I'm missing something). We're already compiling downstream when theming with SCSS what harm can there be from exposing the variables? CSS variables are not some magic bullet, SCSS variables will make sense for years to come. It's disappointing that the material team takes such a restricted stance on styling while being extremely strong on the component architecture. Again, apologies if I don't understand the details well enough, but it doesn't strike me as anyone is trying to solve this.