Skip to content
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

Added contrast verification and readability checking to button. #3131

Merged

Conversation

jorgefilipecosta
Copy link
Member

@jorgefilipecosta jorgefilipecosta commented Oct 24, 2017

This PR aims to address part of #2381, by adding a contrast checking following WCAG 2.0- AA (https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html) to the button.

Testing

Test some colors in button and verify that when contrast is high no message, in low contrast color pairs a message appear.
Verify that when background is darker than text, we suggest making background darker and/or text lighter and when text is darker we suggest making text darker and/or background lighter

Screenshots (jpeg or gifs if applicable):

screen shot 2017-11-08 at 19 50 32

Notes

This verification is implemented thanks to tinycolor2 lib. React-color (used in our color palette) already depends on it. This lib has no external dependencies. A new component was created that uses tinycolor2 to verify readability and then shows the correct warning message.

@jorgefilipecosta jorgefilipecosta added [Feature] UI Components Impacts or related to the UI component system [Feature] Inspector Controls The interface showing block settings and the controls available for each block [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement. labels Oct 24, 2017
@jorgefilipecosta jorgefilipecosta self-assigned this Oct 24, 2017
@jorgefilipecosta jorgefilipecosta added the Needs Design Feedback Needs general design feedback. label Oct 24, 2017
@codecov
Copy link

codecov bot commented Oct 24, 2017

Codecov Report

Merging #3131 into master will decrease coverage by 0.15%.
The diff coverage is 4.54%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3131      +/-   ##
==========================================
- Coverage   34.01%   33.86%   -0.16%     
==========================================
  Files         252      253       +1     
  Lines        6703     6736      +33     
  Branches     1217     1223       +6     
==========================================
+ Hits         2280     2281       +1     
- Misses       3730     3756      +26     
- Partials      693      699       +6
Impacted Files Coverage Δ
blocks/contrast-checker/index.js 0% <0%> (ø)
blocks/library/button/index.js 11.11% <5.55%> (-8.89%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 48ac7a0...db42881. Read the comment docs.

@aaronjorbin
Copy link
Member

aaronjorbin commented Oct 24, 2017

Love where this is going. Helping people make content more accessible is awesome.

Should a state change or event of some sort when the contrast passing state changes? Thinking of the use case of a plugin that wants to block publishing of non-accessible content.

I would love to see some tests of the new code, even though they would essentially be wrappers for testing tinycolor2.

Also cc'ing @afercia so he sees this PR.

@mcsf
Copy link
Contributor

mcsf commented Oct 25, 2017

Nice work!

1. Design-wise, I found it odd that ContrastChecker in the Button block should be rendered inside a PanelBody. I assume this is so that, visually, the notice appears between the two palettes. However, hierarchically, I'm not sure it's the best. I would simply place it as the next sibling of the clear ToggleControl, but I'll leave this up to other reviewers.

2. One rather glaring limitation I found with the Button block is that, if one is using a default color, ContrastChecker can't help the user. Here is an example with a default background color and a custom text color which, together, are clearly not readable:

screen shot 2017-10-24 at 23 46 52

The default color is provided by {style,editor}.scss and so the block logic is unaware of the color. Because these styles are overridable by themes, it would be a bad idea to provide a default color hardcoded in JS.

One hack that I could conceive to work around this would require post-render calls to window.getComputedStyle to read the actual visible color of the button block. I pushed 9c99810 to clarify what I mean, but your best bet is probably to delete that commit (and its parent) from the branch.

@mcsf
Copy link
Contributor

mcsf commented Oct 25, 2017

Ignoring how technically broken(*) my commit is 😁 , one thing it highlights is that the default color pairing (#ffffff over #33b3db) doesn't pass isReadable, regardless of WCAG priority level. /cc @jasmussen

(*): If the block had colors already set and the user then reverts them to default, it takes two renders until the contrast notice appears. This is because fallback colors aren't kept in this.state in order to avoid constant re-renders; this could perhaps be iterated on by saving fallback colors to component state but only ever setting them once: after we've just rendered if we didn't have colors in attributes — meaning the default style was indeed used in the DOM and we can read it. A probably flimsier alternative would be to create a temporary hidden button to read its computed style:

const virtual = this.node.cloneNode();
virtual.style.backgroundColor = ''
virtual.style.display = 'none';
this.node.parentElement.appendChild( virtual );
getComputedStyle( virtual ).backgroundColor // <- grab it
virtual.parentElement.removeChild( virtual );

@jasmussen jasmussen added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Oct 27, 2017
@jasmussen
Copy link
Contributor

Love where this is going. I also like that there's a simple and clear warning message showing up, rather than a for-on-developers-obtuse contrast ratio. It's a win for the regular user. Note that it seemed to take a while for the message to show up for me — it didn't seem to show up for me until I started tweaking the text color (background alone didn't make it show up).

@mcsf

Ignoring how technically broken(*) my commit is 😁 , one thing it highlights is that the default color pairing (#ffffff over #33b3db) doesn't pass isReadable, regardless of WCAG priority level. /cc @jasmussen

Here's a sneak peek at a button redesign ;)

screen shot 2017-10-27 at 09 43 33

@mcsf
Copy link
Contributor

mcsf commented Oct 27, 2017

it didn't seem to show up for me until I started tweaking the text color (background alone didn't make it show up)

That's my own fault, @jasmussen. :) If you git checkout 5e02fb, Jorge's initial commit, the UI responds immediately—with the caveat that it can't detect color contrast if one or both of the colors is the default one.

Here's a sneak peek at a button redesign ;)

\o/

@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch 2 times, most recently from 17f89f6 to 6427758 Compare October 27, 2017 17:53
@jorgefilipecosta
Copy link
Member Author

Hi @aaronjorbin thank you for your sharing your thoughts. Regarding blocking, although that is not yet addressed in this PR, an idea I have in mind is adding to the contrast component an onFail property. Then parent components or other artifacts using their extensibility API (when ready) can make actions when contrast is failing like not allowing publishing.
Regarding testing I totally agree some tests should be added, they were not added yet because we are still prototyping but as soon as we have a clear direction I will add them.

Hi @mcsf thank you for your commits. I like the idea of using the computed styles, the only with this approach is that the color used on the editor may not be the final ones. Some themes change them. One option is adding the CSS of the theme and trying to read the final colors from there (may not be easy). The other option is using different messages for this case something like "Unless your theme uses different colors from the ones being used in the editor...". And the third option is keep things as they are, our message says "may be".

Hi @jasmussen, regarding the refresh problems I added a fix suggested by @mcs, now fallback colors are in the component state and the refresh problems should not happen.
I also changed the contrast verifier to the bottom of the colors and it is always visible even if colors are not.

The last improvements are available to test in the button component,

grabColors() {
const { background, text } = this.containers;
const { textColor, color } = this.props.attributes;
const { fallbackTextColorInState, fallbackBackgroundColorInState } = this.state;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When are these ever set? :)

We can make do with just the truthiness of this.state.fallback*ColorInState.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes my logic had a bug, but the results looked like the expected in tests so I did not notice, it was solved :)

@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch 2 times, most recently from 27d4072 to afa200f Compare October 30, 2017 08:43
@jorgefilipecosta jorgefilipecosta removed the [Status] In Progress Tracking issues with work in progress label Oct 31, 2017
@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch from afa200f to ed56fd8 Compare November 8, 2017 19:45
@jorgefilipecosta jorgefilipecosta changed the title Added contrast verification and readability checking to paragraph and button. Added contrast verification and readability checking to button. Nov 8, 2017
@jorgefilipecosta
Copy link
Member Author

Hi @mcsf, this was rebased and retested :) Could you have a new look and share your thoughts if this is ready or some change is needed?

@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch 3 times, most recently from 554ebb8 to a992853 Compare November 13, 2017 12:44
@jasmussen
Copy link
Contributor

From a UI and functionality pov, this is 👍 👍 to me.

Copy link
Contributor

@mcsf mcsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for working on this!

msg = __( 'This color combination may be hard for people to read. Try using a darker background color and/or a brighter text color.' );
} else {
msg = __( 'This color combination may be hard for people to read. Try using a brighter background color and/or a darker text color.' );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, but this is a good place for a multiline ternary const assignment.

@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch from a992853 to 3a83be4 Compare November 13, 2017 17:44
jorgefilipecosta and others added 4 commits November 13, 2017 17:55
… button.

This verification is implemented thanks to tinycolor2 lib. React-color (used in our color palette) already depends on it, this lib has no external dependencies. A new component was created that uses tinycolor2 to verify readability and then shows the correct warning message.
As an intermediate step before the next commit
This change should solve some refresh problems on contrast verification.
@jorgefilipecosta jorgefilipecosta force-pushed the add/contrast-verification-readibility-checking branch from 3a83be4 to db42881 Compare November 13, 2017 17:55
@jorgefilipecosta jorgefilipecosta merged commit b971d42 into master Nov 13, 2017
@jorgefilipecosta jorgefilipecosta deleted the add/contrast-verification-readibility-checking branch November 13, 2017 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Inspector Controls The interface showing block settings and the controls available for each block [Feature] UI Components Impacts or related to the UI component system [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants