-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Make sure interactive controls are always labeled #51740
Comments
Aside: there's also some inconsistency in the actual HTML output when passing an empty CheckboxControl TextControl This is just to note some code inconsistency. Regardless, controls should always be labeled. |
This made me realize that we sometimes don't even mark the The next step would be to evaluate whether to add runtime checks to emit console warnings in dev mode. Maybe start with some of the common culprits that tend to go unlabeled. I also have a feeling that a lot of unlabeled usages in the wild may be a symptom of our components not being customizable enough. For example, a consumer wants a more custom design for their checkbox label. So this may also warrant a little more deeper investigation. |
A runtime warning could work, although we'd need to check for all ways for an input to be labelled (corresponding I'm not sure about adding the |
I just spotted one more case where the editor renders interactive controls (in this case checkboxes) that are completely unlabelled. Unlabelled controls are, honestly, not acceptable. I'm not using this adjective lightly. It's just not acceptable. The fact they keep being introduced in the editor proves that developers education is not a solution. I'll refrain from further considerations, my intent here is not blaming anyone. Let's just acknowledge the fact that many contributors to this project (developers and reviewers) don't know how to properly label interactive controls and have a little knowledge of the most basic HTML. This is a fact, not a personal judgment, and it is proved by the several occurrences of unlabelled controls that have been introduced in the editor across the history of this project. The point is: how can we remediate to this lack of knowledge?
Honestly I don't mind about consumers of the component who may want to 'go custom'. Functional customization should not be allowed. The priority here is to make sure that in 100% of the cases all controls are labelled.
@ciampo I'd love to have your optimism about developers being able to correctly label elements but unfortunately that's not what happens in the reality, not even in this project. The prove of this is in the recently added 'Fonts' modal dialog, where there are buttons and checkboxes that are completely unlabelled because the Example screenshot: Yes, these checkboxes do have a correctly associated I'd like to be very clear that I'm not willing to blame the authors of this specific implementation. This is just one more case were unlabelled controls have been merged into the codebase. It's a general lack of knowledge in this project that we need to address, in a way or the other. Once again, this proves that these components are open to misuse. I'd consider this a bug and we should fix it soon. @andrewhayward @joedolson @alexstine can we please set some higher priority to this issue? Thanks. |
I think the whole problem here is we are giving developers too much choice. There should have never been a case where we allow components to render a custom label. Label is required for each component or you can implement your own component. We should not be helping developers create inaccessible solutions. That's kind of the whole point of a components library, to avoid anti-patterns but it seems accessibility isn't always a protected piece of the puzzle. The same is even true for the I don't want to blame anyone either, especially the dedicated components team, but there comes a point when you really have to wonder, are we going to force accessibility or keep creating ways for people to ignore it? Thanks. |
💯 I totally second this point. |
And we can all agree on this point.
Having a certain degree of flexibility in how a component can be used can have its value, too (as @mirka also mentioned above). The risk of not allowing folks to add custom labels is that folks will stop using these components when they don't fit their use case, and will resort to simply using another solution (likely as inaccessible, or even worse).
As explained above, we can certainly make some changes, like marking all label props as required. But I don't personally believe that adding runtime checks is a good idea, as also recently discussed in #56231 (reply in thread). I also believe that components will always be open to misuse, in one way or another (for example, folks could disable TypeScript and ESlint errors, or simply ignore the console errors). IMO the best tools that we have to enforce this kind of a11y patterns are tests. Curious to hear if @andrewhayward has any suggestions on this.
I kindly disagree. It is definitely one aspect, but IMO not the whole point.
Let's try to keep a collaborative approach, and remember that we are all working on this project because we share the common goal of improving the WordPress editor. Accessibility is an important piece of a complex puzzle together with many other aspects. Every decision that we take usually involves many compromises. |
From an accessibility perspective, I'm very much in the camp that we should require labels for all interactive controls. This subject is widely covered by research and specifications, and is a vital part of understanding user interfaces. From a developer perspective, as @mirka suggested, this would be easiest to implement by marking interface InputBase {
// ...
};
interface InputWithExplicitLabel extends InputBase {
label: string;
hideLabel?: boolean;
};
interface InputWithImplicitLabel extends InputBase {
label: RefObject<HTMLLabelElement>;
}
interface InputWithLabelledBy extends InputBase {
labelledBy: RefObject<HTMLElement>;
};
type Input = InputWithExplicitLabel | InputWithImplicitLabel | InputWithLabelledBy;
type TextInput = Input & {
// ...
};
type SelectInput = Input & {
// ...
}
// etc Providing a clear and easy way for some controls to hide their label might be a reasonable middle ground here. While I'm not a fan of this approach, as every input should ideally have a visible label, I appreciate that it's better to have a label than not, particularly if it means developers don't instead jump to custom solutions. |
I believe the newest example that @afercia found is definitely a symptom of this — we failed to provide sufficient documentation/APIs to make it easy enough to implement that custom checkbox layout in an accessible way. Before considering any kind of runtime checks, I think we can start there. Make it easier to do the right thing. That starts with TypeScript, documentation, and ensuring that there are APIs/examples to easily ensure correct labeling in custom implementations. |
Hey folks! I've removed the high priority label from this issue as part of a broader sweep of the label. For context, the high priority label needs to be used for top issues that need quick attention. In this case, this is bringing to the surface a very important part of the project but the current solution, from what I'm reading, is more in the realm of the following efforts which is more of an ongoing, consistency issue rather than a need for quick mobilization to fix a top concern:
If this feels off, please just let me know! I'm doing this sweep to make the high priority label as actionable and impactful as possible and want to get this right. |
I think it is still high priority. Every day that this goes unaddressed could mean regressions in our project or others using the components package incorrectly in plugins. For us, we can fix. For 3rd-party developers, it's out of our hands. |
Do we have a label that can mean "this is very important" without meaning "this requires immediate action"? Because this is absolutely a high priority issue, but I agree that it doesn't align with the type of urgency you're describing. But our labeling should have some mechanism to identify longer-term topics that have high priority. |
I think it's time we start adding some eslint rules for this. Starting with |
Description
Any interactive control (inputs, textarea, select, checkboxes, radio buttons, buttons, etc.) should always be labeled. This is a basic accessibility requirement as interactive controls need to inform users what they're about.
Turns out that many (all?) the base components for interactive controls do not enforce any check for some proper labeling nor hey make their
lbel
prop a required prop. This opens the door to developers misuse, as it is possible to:In both cases, the control will be unlabeled. Worth reminding that this is not only about the visual text associated with a control (which usually is a
<label>
element). It's is about the actual accessible name of a control: in case of missing or empty associated<label>
element, missing aria-label / aria-labelledby or any other labeling mechanism, the control accessible name is empty.Being open to misuse, my concern is that these components may potentially contribute to lower the accessibility level of the entire internet, given WordPress is used on millions and millions of web sites.
For no reason, ever, an interactive control should be unlabeled. All these components should enforce proper labeling.
As en example of developers misuse, here's a screenshot from a widely used WordPress plugin for e-commerce:
label
prop, or the prop is omitted entirely.<label>
element, but it's empty.This is very far from ideal. Gutenberg should not allow for unlabeled controls. We can't rely on developers awareness and knowledge. Proper labeling must be enforced by the components themselves. Right now, passing an empty
label
prop or omitting it entirely doesn't even trigger a warning or error.Cc @ciampo @mirka
Step-by-step reproduction instructions
label
prop: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
The text was updated successfully, but these errors were encountered: