-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat(theme): Add support for CSS vars with fallback #4470
Conversation
All 627 screenshot tests passed for commit 5d49c5a vs. |
All 627 screenshot tests passed for commit 7d985e2 vs. |
All 627 screenshot tests passed for commit fd51863 vs. |
All 627 screenshot tests passed for commit 195bcba vs. |
…omponents/material-components-web into feat/theme/vars-with-fallback
All 627 screenshot tests passed for commit a43e2ff vs. |
All 627 screenshot tests passed for commit bdebc93 vs. |
I think this is a great addition to add support for CSS custom property in overriding component styles! 👍 I've a suggestion in the way we use the mixin, instead of changing the style argument structure I added a way to auto detect the presence of CSS custom property and extract the fallback color automatically. // theme/_mixins.scss
@mixin mdc-theme-css-var($property, $var, $important: false, $edgeOptOut: false) {
@if is-css-var($var) {
$fallback-style: get-fallback-style($var); // Extracts fallback color from css custom property.
@include mdc-theme-prop($property, $fallback-style, $important: $important, $edgeOptOut: $edgeOptOut);
@include mdc-theme-prop($property, $var, $important: $important, $edgeOptOut: $edgeOptOut);
} @else {
@include mdc-theme-prop($property, $var, $important: $important, $edgeOptOut: $edgeOptOut)
}
}
// button/_mixins.scss
@mixin mdc-button-container-fill-color($color) {
&:not(:disabled) {
@include mdc-theme-css-var(background-color, $color, $edgeOptOut: true);
}
}
// override.scss
.my-custom-button {
@include mdc-button-container-fill-color(var(--my-custom-button-color, purple));
} WDYT? |
@abhiomkar I originally thought about that but felt the results were a little too "magic." My intention was to make it very clear that a fallback value had to be specified and what role it served. The suggested change also has side-effects for anyone already passing |
All 627 screenshot tests passed for commit f5dfc59 vs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification!
Aren't we already including fallback CSS with theme literals (primary
, secondary
etc)? Do you think adding an additional flag to mdc-theme-prop
mixin (for example, fallback: false
) would resolve opt-in issue?
@@ -129,6 +129,10 @@ $mdc-theme-property-values: ( | |||
// | |||
// NOTE: This function must be defined in _variables.scss instead of _functions.scss to avoid circular imports. | |||
@function mdc-theme-prop-value($style) { | |||
@if mdc-theme-is-var-with-fallback_($style) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning the new style type as is causes an issue to other mixins that uses mdc-theme-prop-value()
function. For example, mdc-card-outline
uses this function to set border-color. mdc-card/_mixins.scss:L303
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we update that line to be as follows?
@include mdc-theme-prop(border-color, $color);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List divider uses the approach described above. I'll include that update in this PR.
@include mdc-theme-prop(border-bottom-color, $color); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused though, what issue was this causing? Do we need to be concerned for existing valid cases of mdc-theme-prop-value being used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is still an issue if component needs to mix colors or apply opacity using rgba()
sass function.
For example, dialog uses rgba()
to apply opacity to color.
dialog/_mixins.scss:
background-color: rgba(mdc-theme-prop-value($color), $opacity);
Where, mdc-theme-prop-value
returns new color format which rgba function doesn't support.
This is another advanced use case where text field uses mix()
function two mix two colors:
textfield/_variables.scss:
$mdc-text-field-background:
mix(mdc-theme-prop-value(on-surface), mdc-theme-prop-value(surface), 4%);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kfranqueiro It shouldn't break existing valid usage. This is an issue only for users who send new color format to component's mixins.
mdc-dialog-title-ink-color('purple'); // works
mdc-dialog-title-ink-color({
varname: '--custom-css-var-ink-color',
fallback: purple
}); // breaks since this applies opacity on given color using rgba
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mdc-theme-prop-value
has been updated to always return the fallback value.
material-components-web/packages/mdc-theme/_variables.scss
Lines 131 to 138 in e58979e
@function mdc-theme-prop-value($style) { | |
@if mdc-theme-is-var-with-fallback_($style) { | |
@return mdc-theme-get-var-fallback_($style); | |
} | |
@if mdc-theme-is-valid-theme-prop-value_($style) { | |
@return $style; | |
} |
All 627 screenshot tests passed for commit ef5d84f vs. |
All 627 screenshot tests passed for commit a0293a0 vs. |
@abhiomkar I think that would only work for the existing CSS custom properties ( |
All 627 screenshot tests passed for commit 65a61b0 vs. |
All 627 screenshot tests passed for commit e58979e vs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@patrickrodee That should work for arbitrary CSS custom properties too if mdc-theme-prop
can detect the presence of CSS customer property and apply fallback CSS value with opt-in flag.
@include mdc-theme-prop(color, var(--my-custom-color, purple), fallback: true);
generates:
color: purple;
color: var(--my-custom-color, purple);
@@ -110,6 +110,38 @@ Property Name | Description | |||
`on-secondary` | A text/iconography color that is usable on top of secondary color | |||
`on-surface` | A text/iconography color that is usable on top of surface color | |||
|
|||
#### `mdc-theme-prop` with CSS Custom Properties | |||
|
|||
> **Note** The Sass map `$style` argument is intended *only* for use with color mixins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we can't use it for other CSS properties. We aren't doing anything specific with color in our implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested it for other CSS custom properties. I'd rather scope this to what it was intended for. We can always remove this line from the docs at a later date.
|
||
``` | ||
.foo { | ||
@include mdc-theme-prop(color, ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand this correctly, this is equivalent to applying same mixin with CSS custom property and regular CSS value?
mdc-button-fill-color(purple);
mdc-button-fill-color(var(--my-custom-button, purple));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output CSS is pretty different. Calling both mixins includes the full selector twice. Below is an approximation of the output CSS:
.mdc-button {
background-color: purple;
}
.mdc-button {
background-color: var(--my-custom-button, purple);
}
All 627 screenshot tests passed for commit 5643f95 vs. |
All 627 screenshot tests passed for commit b92a208 vs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
…al-components#4470) (cherry picked from commit 0bfb393)
What this does
Add the ability to specify a CSS custom property name and fallback for color mixins. Allows clients that can support CSS custom property theming to use that when desired without breaking browsers that do not support CSS custom properties.
What this does not do
This does not establish naming conventions for CSS custom properties. Those names are entirely up to the developers who use this feature.
Usage
The generated CSS is as follows:
This CSS allows for browsers that do not support CSS custom properties to default to the fallback (purple) while still supporting an overridable CSS custom property
--my-custom-button-fill
.