Skip to content

Allow palettes to specify a separate hue for uncontained text #15148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
benelliott opened this issue Feb 11, 2019 · 8 comments · Fixed by #15149
Closed

Allow palettes to specify a separate hue for uncontained text #15148

benelliott opened this issue Feb 11, 2019 · 8 comments · Fixed by #15149
Labels
Accessibility This issue is related to accessibility (a11y) feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@benelliott
Copy link
Contributor

Please describe the feature you would like to request.

There is a lot of emphasis on making sure that you choose accessible text colors to ensure readability when your palette color is used in the background but there is no such concern when your palette color itself is used as the text color on a neutral background. This is exacerbated by the fact that @angular/material components will implicitly use the default hue of the palette when selecting this text color - for example in _form-field_theme.scss:

$focused-label-color: mat-color($primary);

it's very hard to pick a palette whose primary is effective both as a strong background color and as a strong text color for small text on a neutral background and conforms to any existing brand guidelines.

One way to fix this would be to extend mat-palette with a fourth argument, $text. For compatibility it could default to $default if not specified, but this would allow you to use a much darker hue on form field labels and so on without making primary backgrounds darker everywhere else.

You can quite easily see the accessibility issues with the current system with some of the prepackaged themes. For instance setting the theme to purple-green on https://material.angular.io/components/form-field/examples gives a contrast ratio of 2.09 for the form field inputs.

What is the use-case or motivation for this proposal?

Improves accessibility

Is there anything else we should know?

No

benelliott added a commit to benelliott/material2 that referenced this issue Feb 11, 2019
benelliott added a commit to benelliott/material2 that referenced this issue Apr 18, 2019
@andrewseguin andrewseguin added Accessibility This issue is related to accessibility (a11y) docs This issue is related to documentation feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed docs This issue is related to documentation labels May 7, 2019
benelliott added a commit to benelliott/material2 that referenced this issue May 24, 2019
@thw0rted
Copy link

I've been looking at a few issues (#13905, #15672) with colored text in dark themes. Defaulting the text value to 500 means that when a theme color (primary/accent) is used for text it will have poor contrast on dark backgrounds. Ideally you could have the text be a light tone (50/100/200) for dark themes and a dark tone (600/700) on a light theme, but of course when you're constructing a mat-palette you don't know what mat-*-theme function it will be passed to.

I know the PR is already merged, but I have an alternate proposal. In all the places where the text key is referenced (*-theme.scss), instead of e.g. _mat-button-theme-property($theme, 'color', text);, you could write _mat-button-theme-property($theme, 'color', if($is-dark-theme, lighter, darker));. This relies on existing light/dark variants while providing accessible contrast on both types of background. Of course it gives less control than an explicit text value. I'm not a Sass master but maybe there's a way to have no default value for text and fall back to lighter/darker in context when consuming it (i.e. in the individual -theme files)?

If you don't agree with this change, we're going to either need a fifth hue, for separate light-text and dark-text, or at least we'd need to update theme creation documentation to state that mat-palette always creates palettes that are not suitable for use with mat-dark-theme unless you specify a text, which doesn't seem very developer-friendly.

@thw0rted
Copy link

Oh, and I guess cc @benelliott and @josephperrott

@benelliott
Copy link
Contributor Author

@thw0rted The problem with not defaulting to 500 is that it will be a huge breaking change that invalidates a lot of screenshot diffs for apps inside Google (I know because I accidentally did it with this PR initially 😄). AFAIK because of how Angular is deployed inside Google it would then be the Material team's responsibility to go in and "fix" each of these independently.

Moving forward though I definitely agree - this PR goes some way to helping the situation but it's quite easy to find situations where it still falls down. I think this will always be true however just due to the sheer number of text/background colour combinations you can end up with even within the theming engine.

@thw0rted
Copy link

If I understand the situation correctly, the text key didn't exist a few months ago, so anybody referring to it must have added such references quite recently. I think this is a good opportunity to reconsider how all of us use color and make sure we're always doing it in a background-sensitive way, to make sure we meet a11y requirements. Dark is becoming more popular and also more widely supported, so anything we can do to get away from treating light as "default" is a real improvement.

All that to say: if it continues to default to 500, text doesn't really mean "text", it means "text in a light theme". And actually, thanks to snackbar, it's even more specific than that: it's "text on a standard background in a light theme, or on an inverted background e.g. snackbar, in a dark theme". Either kind of theme actually needs the inverse as well, so that a dark-theme snackbar (with a white background) can have a more-saturated tone for its action text.

How would you feel about that? I don't know what name would be appropriate, or if it's too late to change the name of the current fourth-argument key, but it sounds increasingly likely that either we need 3 keys (default, darker, lighter) or 5 (those plus "dark-tone text" and "light-tone text").

@benelliott
Copy link
Contributor Author

benelliott commented Jul 22, 2019

So, having thought about this for a while and looking at the comments in https://github.com/angular/components/blob/master/src/material/core/theming/_theming.scss#L12, I feel like an invocation of mat-palette needs to be interpreted as being specific to a
(light or dark) theme rather than an invariant set of colors.

The base palette is the invariant but the mat-palette configuration (the base palette plus the selection of hues for light/dark/text) is not.

This means that when you build a light or dark theme you need to create a mat-palette with hues that are selected for that particular theme. So if you are building a dark theme, you should pick paler hues from your base palette for the text hue and so on.

Obviously this doesn't mean that there will be a good contrast ratio in all cases - you might still override the "dark grey" background color with a pale background color in some of your components' CSS for example. But there is no real way for the theming engine to detect that at build time.

The above suggests that there should be light and dark variants of any predefined palettes in order to ensure a decent contrast ratio in all cases. So the pink mat-palette in the dark "pink-bluegrey" theme should have a different text hue than a pink mat-palette in a light "pink-bluegrey" theme.

Coming back to setting 500 as the default - this is purely for backwards compatibility currently. I don't disagree that 500 will be suboptimal for text contrast in a lot of (most?) cases but changing it would mean that apps inside Google break unless they start explicitly defining a text hue in their own palettes. I don't know what the appetite for such a big change would be within the Material team.

Snackbar is currently a bit of an outlier because its theme colors are very hard-coded, even going as far as having an inline hex value in the theme.scss: https://github.com/angular/components/blob/master/src/material/snack-bar/_snack-bar-theme.scss#L13

This pushes me towards the idea that inverted components (like snackbar) should be themed by a separate inverted theme property. It would get rid of any hard-coded values and would also mean we could avoid workarounds like https://github.com/angular/components/blob/master/src/material/snack-bar/_snack-bar-theme.scss#L10. Plus, it would mean that users could further customize their theme if, for example, they wanted a dark snackbar on a dark theme (e.g. for a night mode UI).

@thw0rted
Copy link

I get your point about having a theme-specific palette, and it makes sense. Are you suggesting a fifth palette argument for inverted? If so, would that fall under this issue, or would it merit a separate issue? Unfortunately that keeps us thinking "light as default", but maybe that's not a fight I can win. It would have to default to a light tone, maybe 100, I guess.

You mention Snackbar: adding an explicit inverted tone would make it easy to resolve #13905. As you point out, that hard-coded inline hex is a spec violation.

@benelliott
Copy link
Contributor Author

I was actually thinking that the inverted theme would have to be a whole theme in its own right (so, a level or two up from the palette) - but still thinking about if/how this would actually work (+ without massively bloating everyone's CSS!)

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) feature This issue represents a new feature or feature request rather than a bug or bug fix P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants