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

Contrast checker notice should not use the order CSS property #58936

Open
afercia opened this issue Feb 12, 2024 · 16 comments · May be fixed by #68055
Open

Contrast checker notice should not use the order CSS property #58936

afercia opened this issue Feb 12, 2024 · 16 comments · May be fixed by #68055
Assignees
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Package] Block editor /packages/block-editor [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended

Comments

@afercia
Copy link
Contributor

afercia commented Feb 12, 2024

Description

  • Go in the post editor or site editor.
  • Select a paragraph
  • In the inspector panel, set background and text colors to trigger the color contrast checker notice.
  • In the browser dev tools, select the element with CSS class block-editor-contrast-checker
  • Observee the element has a CSS property order: 9999;

See the comment in the code at

.block-editor-contrast-checker {
/**
* Contrast checkers are forced to the bottom of the panel so all
* injected color controls can appear as a single item group without
* the contrast checkers suddenly appearing between items.
*/
order: 9999;

Introduced in 8675f86
See the related PR description that mentions this point
#34027

Instead, this PR simply replicates the styling of the ItemGroup and leverages CSS ordering to force contrast checkers to the bottom of the panel.

I'm not sure this order property is still necessary. In any case, visual order and DOM order must always match when they affect 'meaning and operation'. Reference:

WCAG 2.2
1.3.2 Meaningful Sequence (Level A) https://www.w3.org/TR/WCAG22/#meaningful-sequence
2.4.3 Focus Order (Level A) https://www.w3.org/TR/WCAG22/#focus-order

If this CSS property is no longer necessary, we should just remove it.
If the order issue mentioned in the oroginal PR is still relevant, another solution must be found as the DOM order must match the reading order.

Cc @aaronrobertshaw

Step-by-step reproduction instructions

See instructions above.

Screenshots, screen recording, code snippet

No response

Environment info

No response

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@afercia afercia added [Type] Bug An existing feature does not function as intended [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Block editor /packages/block-editor labels Feb 12, 2024
@aaronrobertshaw
Copy link
Contributor

Thanks for the ping @afercia 👍

If this CSS property is no longer necessary, we should just remove it.

The CSS property is still required as the color panel can have controls inserted via slot fills from any number of sources.

If the order issue mentioned in the oroginal PR is still relevant, another solution must be found as the DOM order must match the reading order.

The order is still relevant as it keeps the related color controls together. I'm not sure what other solutions are available to us that wouldn't break the UI further. Perhaps we need some fresh design eyes on this one?

WCAG 2.2
1.3.2 Meaningful Sequence (Level A) https://www.w3.org/TR/WCAG22/#meaningful-sequence
2.4.3 Focus Order (Level A) https://www.w3.org/TR/WCAG22/#focus-order

So I'm clear, are you saying the sequence here is meaningful or is there a problem with the focus order?

I think an argument could be made here that the contrast checkers' meaning is independent from the sequence in the DOM. It's unfortunate that we can't control the order of slot fills otherwise their injection to the panel could be separated and moved to the end of the panel.

I'm a little short on bandwidth at the moment, so if there is anyone that can pick this up that would be appreciated. I'd of course be happy to help out with reviews etc.

@afercia
Copy link
Contributor Author

afercia commented Mar 20, 2024

The CSS property is still required as the color panel can have controls inserted via slot fills from any number of sources.

It would be nice to understand how to replicate this scenario and actually test the UI with altered order.

So I'm clear, are you saying the sequence here is meaningful or is there a problem with the focus order?

It's not just about the focus order. it's also about the reading order.

The order is still relevant as it keeps the related color controls together.

To my understanding, it will only keep the visual order of the color controls together. The DOM order will not match the visual order though.

@aaronrobertshaw
Copy link
Contributor

It would be nice to understand how to replicate this scenario and actually teste the UI with altered order.

I'm not sure I can give an explicit step-by-step recipe for testing. There are so many possibilities, it would change I think based on what your testing focus is.

There are a few key points that I can note that should help you create a tailored test case:

  • The controls in the Color panel are rendered via a single slot
  • They are added via <InspectorControls group="color">{ elements for panel go here }</InspectorControls>
  • Color block supports inject their "standard" color controls via that same means
  • Individual blocks can add their own controls e.g. Cover block
  • There are no restrictions on the type of elements that can be added to the panel e.g. Cover's overlay opacity control
  • Plugins could override and extend a block adding further controls
  • The controls added would be dependent on the load order of plugins etc as well
  • SlotFills can't guarantee the DOM order of their fills

Again, I appreciate that isn't quite what you might have been chasing but I hope it helps somewhat though.

As the various inspector panels have matured a bit, it would be good to revisit the color panel as a special case. There could be some benefit to exploring multiple slots just for that panel. That could still have some backwards compatibility issues to wrangle as well as the fact that the slots would still be open to 3rd parties. I'm not sure even then we could guarantee controls aren't placed as fills in the wrong slot and/or disrupting meaningful order (visual or DOM).

Unfortunately, I don't have the bandwidth to explore this further. I'd be happy to help test or review any potential solutions though 🙏

@afercia
Copy link
Contributor Author

afercia commented Apr 15, 2024

@aaronrobertshaw I found some time to wrap my head around this issue. Thanks for your detailed explanation, much appreciated.

I played a bit with altering the Cover block code, just for testing. Still, this order CSS property doesn't seem ideal to me. The ContrastChecker can also be added manually to a stack of components added via the slot. As a developer, I would expect to see the ContrastChecker being rendered in the exact place where I placed it.

As a user, the ContrastChecker makes sense only when it is rendered right after the setting that has an invalid color pair. Instead, it is always moved at the bottom in the last position. As such, it is 'detached' from the invalid setting. It is confusing and not the best UI because it's not immediate to understand which setting is invalid.

See the example screenshot below.
On the left: the red arrow illustrates where the ContrastChecker is supposed to be shown, right after a control that may have incalid color pair.
Instead (on the right) it is moved as last. Even after the control that is placed last in the stack of controls within the <InspectorControls group="color">.

This is an user experience problem.

Not sure this is ideal. Ideally there should be a way to 'attach' the ContrastChecker to a specific control and not render it via the slot.

Screenshot 2024-04-15 at 16 52 55

@aaronrobertshaw
Copy link
Contributor

As a developer, I would expect to see the ContrastChecker being rendered in the exact place where I placed it.

I'm not sure this could be guaranteed given SlotFills can't guarantee the order in which their fills will be registered and rendered.

As a user, the ContrastChecker makes sense only when it is rendered right after the setting that has an invalid color pair.

It could also be worth factoring into this discussion that the contrast checkers are really related to more than a single control or color value. The warning is based on how the selection relates to other selections for other color controls. In some circumstances, it could be argued that the contrast checker relates to the overall color configuration for the panel.

Not sure this is ideal. Ideally there should be a way to 'attach' the ContrastChecker to a specific control and not render it via the slot.

The example shown is pretty specific to the Cover block because of the two overlay-related controls. The contrast warning there makes sense given it's after the color controls but before the overlay opacity.

If the contrast warning was related to the heading color and was tied to it, it would break the visual representation of grouping the color controls. I'm not arguing for or against anything here, just that that is the consequence. So to make any changes to strictly tie the contrast warning with the control it relates to would need an alternate design.

If we are to try and maintain the current visuals but detach the contrast checker and color controls, then I think it comes back to earlier suggestions made about potentially introducing additional slots for the color panel.

@afercia
Copy link
Contributor Author

afercia commented Apr 16, 2024

The contrast warning there makes sense given it's after the color controls but before the overlay opacity.

It's before the overlay opacity in the screenshot on the right, where I removed the order CSS property 🙂
Overall, I think this order property should be removed as a first step to improve the usage of the ContrastChecker.

If the contrast warning was related to the heading color and was tied to it, it would break the visual representation of grouping the color controls. I'm not arguing for or against anything here, just that that is the consequence. So to make any changes to strictly tie the contrast warning with the control it relates to would need an alternate design.

Not sure 'breaking the visual representation' would be a huge issue. A notice or warning are supposed to appear in close proximity with the control that is invalid. That is expected. Imagine a form with many input fields. The form has user input validation. Once submitted with an invalid value, the validation error message can certainly be shown at the top or at the bottom of the form but there is the need to identify the invalid value and point users to it. Usually, the validation error is shown close to the invalid field.

Instead, in this csse there's no way to identify which one of the potential multiple color settings is invalid. Imagine a block with multiple color pair settings. The notice only says 'this color combination' but there's more than one and no indication at all of which one is invalid. Plugins can also add more controls and custom blocks may provide multiple color controls and still the ContrastChecked would not indicate which setting is invalid.

On top of that, the visual order and DOM order must match anyways.

I will prepare a quick PR to remove the order property but I totally agree this needs to be improved and probably needs design.

@aaronrobertshaw aaronrobertshaw added the Needs Design Feedback Needs general design feedback. label Apr 16, 2024
@aaronrobertshaw
Copy link
Contributor

I will prepare a quick PR to remove the order property but I totally agree this needs to be improved and probably needs design.

Before jumping too deep into a PR, it might pay to get that design input upfront on this one. Possible solutions can then be discussed and settled upon here.

I've added the Needs Design Feedback label to get the ball rolling.

@afercia
Copy link
Contributor Author

afercia commented Apr 16, 2024

Before jumping too deep into a PR, it might pay to get that design input upfront on this one. Possible solutions can then be discussed and settled upon here.

I think a new design and the order CSS property are two separate issues. I will submit a one-line PR to remove the order property. Anyways, I did some testing and it seems to me the contrast checker within the color group is always rendered last anyways so that I'm not sure the order property is necessary in the first place.

I'd think the need for a new design and new implementation is a separate issue. The way the contrast checker is used isn't great. For example the Navigation block uses two contrast checkers for two color pair settings. When other color pairs are invalid, the UI isn't that great, honestly. Screenshot:

Screenshot 2024-04-16 at 15 29 34

I still think the contrast checker notice should be visually tied to the color pair it is associated to.

@aaronrobertshaw
Copy link
Contributor

Anyways, I did some testing and it seems to me the contrast checker within the color group is always rendered last anyways so that I'm not sure the order property is necessary in the first place.

Apologies for my confusion here @afercia. It appears how the contrast checkers are added changed with #48893.

I also couldn't replicate the multiple contrast checkers for the navigation block but the contrast checking still appeared a bit broken.

Screen.Recording.2024-04-17.at.4.08.05.PM.mp4

Unfortunately, as noted before, I'm rather short on bandwidth for the foreseeable future, so I'll have to leave this issue with you.

@afercia
Copy link
Contributor Author

afercia commented Apr 17, 2024

Thanks @aaronrobertshaw I will create a couple seeparate issues as the ContrastCheckeer appears to be buggy anyways.

I also couldn't replicate the multiple contrast checkers for the navigation block

For me, it doesn't work well when I set a color pair the first time. It only works when I change an already set color pair. For the navigation block specifically, I have to set/change color on both pairs to trigger both the notices. See GIF below, from latest trunk:

contrast checker

@afercia
Copy link
Contributor Author

afercia commented Apr 30, 2024

It appears how the contrast checkers are added changed with #48893.

@aaronrobertshaw thanks. Is this the relevant commit? d5297f2

Does that mean that, since the contrast check is performed on every render, the notice will always rendered last?
If that's the case, the order CSS property could be removed safely.

@aaronrobertshaw
Copy link
Contributor

Is this the relevant commit? d5297f2

At a glance, I don't think that's related to where a contrast checker is rendered.

The Navigation block rendering its own additional contrast checkers does show the potential for the fills rendered to the color panel slot to contain additional contrast checkers. Depending on what else is rendered to the panel, those contrast checkers would not be last.

Take an example where a 3rd party block adopts text and background block support which adds text and background controls plus a contrast checker. The block then also injects two custom color controls for an inner area of the block which require their own contrast checking for the a11y of that area. Without being able to guarantee the order of fills for a slot, the custom controls with their contrast checker could come before the block support controls and their contrast checker resulting in something like:

<ColorPanel>
    <CustomColor1 />
    <CustomColor2 />
    <ContrastCheckerFor1Vs2 />
    <TextColor />
    <BackgroundColor />
    <ContrastCheckerForTextVsBackground />
</ColorPanel>

@afercia
Copy link
Contributor Author

afercia commented May 3, 2024

Thanks for the explanation @aaronrobertshaw
The potential order you illustrated above:

    <CustomColor1 />
    <CustomColor2 />
    <ContrastCheckerFor1Vs2 />

    <TextColor />
    <BackgroundColor />
    <ContrastCheckerForTextVsBackground />

is exactly what I would like to see. From an usability and accessibility perspective, the contrast checked notice should appear immediately after the color pair it relates to. Otherwise, it wouldn't be clear which color pari the notice is warning about.

@aaronrobertshaw
Copy link
Contributor

Understood 👍

This brings the discussion back to my earlier comments around needing design feedback, as displaying the contrast checker as per the example structure order, would break the "item group" representation of all the color controls.

@afercia
Copy link
Contributor Author

afercia commented Dec 17, 2024

It appears how the contrast checkers are added changed with #48893.

Looking back into this issue, to my understanding ContrastChecker isn't added via a slot / fill any longer. As far as I can tell on current trunk, excluding the native files, it is used:

As such, i tseems to me the CSS order property is no longer necessary.

@github-actions github-actions bot added the [Status] In Progress Tracking issues with work in progress label Dec 17, 2024
@aaronrobertshaw
Copy link
Contributor

to my understanding ContrastChecker isn't added via a slot / fill any longer

The contents of the Color panel are still rendered via a slot fill for block inspector controls of block instances.

You can see in the color block support hook here that it is passed an as prop making it a ColorInspectorControl which renders to the color group slot in inspector controls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Package] Block editor /packages/block-editor [Status] In Progress Tracking issues with work in progress [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants