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

Disabled blocks: identify alternatives to "inert" #54369

Open
ramonjd opened this issue Sep 12, 2023 · 18 comments
Open

Disabled blocks: identify alternatives to "inert" #54369

ramonjd opened this issue Sep 12, 2023 · 18 comments
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility Needs Decision Needs a decision to be actionable or relevant [Package] Components /packages/components [Type] Discussion For issues that are high-level and not yet ready to implement. [Type] Enhancement A suggestion for improvement. [Type] Question Questions about the design or development of the editor.

Comments

@ramonjd
Copy link
Member

ramonjd commented Sep 12, 2023

Gutenberg's use of "inert"

Gutenberg uses the inert HTML attribute to disable blocks in the editor.

For instance, in the useDisabled hook and on template parts when editing a page in the Site Editor (via useBlockProps).

The assumption is that Gutenberg should have a good reason to disable blocks.

The use of "inert" on disabled blocks impacts accessibility by hiding them from the accessibility tree. In cases where disabled content conveys information in some way, or has, albeit, limited interaction, screen readers/keyboard users have no knowledge of its purpose or existence.

The argument for using "inert" in the editor is that disabled blocks are, as far as the browser and user are concerned, functionally "hidden". They are unfocusable and non-interactive and therefore serve no purpose other than placeholders.
Could the editor communicate this intention in another way while retaining "inert"? For example a label that describes the disabled state and what is being disabled?

Related discussions:

Alternatives

I'm not proposing any specific approach, just trying to collate and summarize various discussions.

A proposed approach would be to create a general callback to prevent default behaviour via event handlers, potentially via event delegation/capturing on the editor container. For example, click, focus, keyDown, change etc.

To disable interaction for all core blocks while maintaining keyboard navigation would be challenging. Each core block is unique. Take for example the search block, which contains several focusable elements including a input field and a rich text component.

More time consuming, each block could handle its own disabled state separately. So, the idea is that a block would receive a prop to inform it that it has been "disabled" in the editor and it would render itself accordingly. Perhaps something similar to how the ally library disables elements.

Here's an example of a PR that attempts to accomplish this for the table block:

Questions

  • Are there any short term alternatives, such as labels that describe the disable areas?
  • For sighted users, should there furthermore be a visual indication that a block is disabled?

Related reading

@ramonjd ramonjd added [Type] Enhancement A suggestion for improvement. [Type] Question Questions about the design or development of the editor. [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Decision Needs a decision to be actionable or relevant Needs Accessibility Feedback Need input from accessibility [Type] Discussion For issues that are high-level and not yet ready to implement. labels Sep 12, 2023
@alexstine
Copy link
Contributor

Let me start with some thoughts. Its a little after 10PM here so none of these are meant to be taken as mean, but sometimes my point of view can be a little strong.

  1. Inert content is not something that should never be used, it just shouldn't be used for blocks in this way. For example, using inert on content outside of a modal would be a great use of the attribute to prevent any interactions from closing said modal. The modal generally covers much of the page so it is unimportant that screen readers have context for anything outside of modal content.
  2. When using inert on a block, screen reader users do not have an equal experience to sighted users.
  3. Sighted users can clearly see a search form and a submit button in the case of the search block.
  4. Screen reader users would get nothing.
  5. Labels do not meet this requirement because it would be up to developers to describe the block content leaving us with the same problem of accessibility is hard. Simply having a label that says "this block is read-only" still does not give non-sighted users the same experience.
  6. Unlike the disabled attribute, inert totally removes the element or elements from the accessibility tree. Disabled attribute only prevents focus, it does not remove the element from screen readers virtual DOM view.
  7. Let's read the docs together, shall we?
    https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert

Prevents the click event from being fired when the user clicks on the element.

Seems reasonable.

Prevents the focus event from being raised by preventing the element from gaining focus.

This is a good first step to making an element inaccessible but it is still accessible via virtual navigation. Not totally broken yet.

Hides the element and its content from assistive technologies by excluding them from the accessibility tree.

This is the final death sentence. At this point, screen reader users are now fully excluded from anything that sighted users may get from seeing the back-end block content. This is essentially the same as aria-hidden="true" with tabindex="-1" with additional event restrictions.

Instead, why not write a hook that does this?

  1. Feed in the block content.
  2. Search for form fields to disable.
  3. Add aria-disabled="true" to communicate disabled to screen readers.
  4. Attach event listeners to prevent click on any element that can receive a click. Hint, this requires valid HTML in the first place. 🙂 Sorry, couldn't resist.
  5. Add some type of description to the block telling users why the content is disabled.

What I can't get over is how this problem started and how it has developed to this point. I am not sure why any developers who work on the project thought it was a good idea to work this hard at making sure blocks match the front-end while simultaneously excluding blind users. Being totally honest, I really don't care if this is how it is done in other editors or websites. Gutenberg should be better than this and I will do my best to help us get there. I enjoy working on Gutenberg because I think it can be better than the status quo but not if everyone keeps comparing it to what already exists on the web. If it were really that simple, I imagine there is no reason for any of us to keep working on Gutenberg in the first place. I see it time and time again. X/Y/Z does it like this...

One final note. The argument about sighted people needing to see content that screen readers don't is not applicable to this situation. Let's think about it.

  1. Screen readers should never be given more information than what is presented to non-screen reader users. This means good UX and great UIs for this to be possible.
  2. This problem was created because using inert, screen readers do not have equal access that someone with sight would have.
  3. If the content is truly not important, let's just remove it from the block all together. It can render on the front-end and no one sees it on the back-end. This allows an equal experience for both non-sighted and sighted users. It would be a pain for both groups of people to constantly need to preview the front-end.

Looking forward to solutions/proposals on how to move this forward.

Thanks.

@alexstine
Copy link
Contributor

BTW, I just gave the search block a test and it looks like inert or disabled are not being used. They are just basic inputs that allow you to customize the output on the front-end. What I can see in the code, the block does not have any type of preview.

@youknowriad
Copy link
Contributor

I've shared more context here #44865 (comment)

Our usage of disabled or/and inert is basically done to mimic images/screenshots, we don't want the content of these divs to be navigable or accessible to sighted or screen reader users, we want these to just be screenshots/previews.

In that sense, I think the solution is to use role="img" with a label when we use that. Just make these containers work like images.

@alexstine
Copy link
Contributor

alexstine commented Sep 12, 2023

As I stated in a previous comment, I don't like the idea of allowing subjective labels.

  1. Developers will need to properly describe every element of the block.
  2. Developers will need to remember to update this description when the block changes.

Both of which I am certain will never happen.

Its a good idea but probably not super practical in the real world. I am also trying to figure out how this is solved for 3rd-party blocks.

I'll take it a step further. Instead of using real HTML, why not have the developer take multiple screenshots of the front-end and display them conditionally based on block settings?

Here is a good example. In my Table of Contents block changes, I exposed all the links to screen readers but disabled them. To get the same effect for users, you would need to write a description like this.

Table of Contents block containing a list of headings which are numbered.

  1. X
  2. Y
  3. Z

The description would have to be dynamic so that screen reader users always get the same back-end experience that they would have on the front-end.

The other option? Disable the form controls and stop using inert.

CC: @joedolson @afercia

Maybe they have other opinions that differ from mine.

Thanks.

@alexstine
Copy link
Contributor

First attempt at fixing the comments form block: #54393

Thinking about this further, @youknowriad is probably correct about some blocks. For example, in comment content, there is no easy way to disable parts of rendered HTML. We have no idea what a user may enter for comments content and this might be one of the situations where disabling the block is necessary. For the blocks that are under our control, I still suggest keeping them as accessible as possible.

@joedolson
Copy link
Contributor

We need to be careful about ensuring that all users have at least a roughly equal access to whatever information is being hidden; and inert doesn't have the same impact on sighted users as it does for screen reader users. There are certainly scenarios where it's reasonable to specify everything as unavailable; we just need to remember that as long as the content is visible, sighted users can read it and know what's in that container; screen reader users don't get that information.

So, if the content is truly intended to be unavailable, why not just replace it with blank space? If it's considered important that the content is visible to some users, then it needs to be visible to all users. So we need a strategy that will expose the relevant information to screen readers or we should not expose any information about the block to sighted users. As it is, we're using a technique that explicitly favors sighted users.

@ramonjd
Copy link
Member Author

ramonjd commented Sep 13, 2023

Our usage of disabled or/and inert is basically done to mimic images/screenshots, we don't want the content of these divs to be navigable or accessible to sighted or screen reader users, we want these to just be screenshots/previews.

Thanks for the input, everyone.

I'd extend this analogy to the template visualizations surrounding page editing in the site editor. (Related discussion), but I do understand the argument for parity and disclosing what it is we're hiding.

If non-sighted users/keyboard should know more precisely about these areas, perhaps it'd be possible to describe them in general terms and ensure that can be easily "activated" by keyboard, for example, "A header template containing the following blocks: A, B, C.... Click to edit/interact"

This, in my mind, would better match the functionality and offer access to the hidden elements underneath, which in total reflects the behavior of the visual editor.

Ultimately, when editing a page in the Site Editor the only thing one can do is edit the page content unless they explicitly activate template editing.

Once again I'm speaking specifically to the Site Editor's use of inert template areas around a page, not lower level block accessibility concerns such as those address in #54393.

@alexstine
Copy link
Contributor

@ramonjd Could you please tell me specific steps to edit a page in the Site Editor out of template mode? I want to see it for myself but the Site Editor is still largely confusing to me so want to make sure I can get a look at what I intend to look at.

Thanks.

@ramonjd
Copy link
Member Author

ramonjd commented Sep 13, 2023

Could you please tell me specific steps to edit a page in the Site Editor out of template mode? I want to see it for myself but the Site Editor is still largely confusing to me so want to make sure I can get a look at what I intend to look at.

Sure! It'd be great to hear about your experience with this journey. As I understand it, the Site Editor still needs a lot of love. Especially, the navigation menus in view mode, which are still relatively new (since WordPress 6.3). It would be great to also know if the navigation needs better labelling too.

Here are the steps:

  1. First go to the Site Editor. Here is the URL path: /wp-admin/site-editor.php
  2. From the navigation list, select the "Pages" item. Here is the URL path: /wp-admin/site-editor.php?path=%2Fpage
  3. From the pages list, select a page other than the home page. E.g., one of the default 2023 theme pages, like "Sample page".
  4. In the single page item view, click on the "Edit" button to enable edit mode in the Site Editor.
  5. From here you should be able to edit the Page's content in the editor. For example, page title, featured image and page content.
  6. To enable template editing, open the page inspector via "Settings" , then "Page".
  7. In the "Summary" pane, select "Template options" to open the menu. Then select "Edit template".

The main functional difference I see, and at first sight I'd consider it an area for improvement, is that mouse users can also activate template edit mode, that is, everything in steps 6 and 7 from the list above, by clicking outside the page content. As far as I can see, this has not yet been implemented for keyboard users.

@ramonjd
Copy link
Member Author

ramonjd commented Sep 13, 2023

I might add, on the topic of page editing in the site editor: there is a PR in the works that allows toggling the visibility of surrounding (disabled) template areas on and off. The default template visibility will be off it appears from the PR.

@alexstine
Copy link
Contributor

@ramonjd If you look near the end of the hallway hangout, I believe I found this.

https://make.wordpress.org/test/2023/09/14/hallway-hangout-lets-chat-about-improving-accessibility-in-the-site-editor/

You will see where I tried to select the comments form block from the list view and nothing happened. The inert was on the block wrapper and I think that is the same thing you are describing above.

We really need to figure out a better way to handle this.

Thanks.

@ramonjd
Copy link
Member Author

ramonjd commented Sep 22, 2023

You will see where I tried to select the comments form block from the list view and nothing happened.

Thanks for sharing @alexstine

I think there's definitely a disconnect there between what's happening in the list view and what's in the editor, so I agree that there's some work to be done at the block level here. And/or better synching between the list view and editor block lists.

@andrewserong
Copy link
Contributor

Just linking together that another issue with inert is present in #55177 where the writing flow keyboard navigation is affected by the presence of the inert attribute. There is a short-term workaround for the keyboard behaviour in #55221, but in the longer-term it'd likely be preferable to find an alternative to inert so that when navigating via keyboard, folks can logically move up and down between regular blocks and synced patterns / template parts. (In addition to the other issues already raised in this discussion).

@afercia afercia added the [Package] Components /packages/components label Jan 4, 2024
@afercia
Copy link
Contributor

afercia commented Jan 4, 2024

Just noticed that inert is used also for the Disabled component, which wraps some of the blocks in the editor. For example: the Archive block is completely 'empty' for screen readers, regardless whether it set to show a list of a dropdown.
Noting is announced or can be interactive with when using a screen reader. It appears it also triggers some unexpected keyboard interaction when tabbing through blocks in the editor.

@talldan
Copy link
Contributor

talldan commented Jul 9, 2024

I was directed here from #62935.

There is already functionality to add a description to a block (via the block label), but I worry that it wouldn't be possible to provide enough information about what's in a block. Especially considering it's often an entire block hierarchy that's made inert.

If you take the example of editing a page with the template visible, a screenreader user should really be able to read the inert parts of the template the same way a sighted user has (use case - making sure the right template is selected). It seems like a big disadvantage that this is not possible without editing the template itself and inspecting the contents. Also some users might not have access to do that based on the user role.

Some kind of read-only mode for html elements would be the ideal solution, but that doesn't exist AFAIK (only for form elements).

I did wonder whether something like renderToStaticMarkup might be a possibility (https://react.dev/reference/react-dom/server/renderToStaticMarkup), but there's the caveat that it'd need to support nested blocks that are enabled.

I'm a bit lacking in other ideas though that don't involve changing every single block's implementation.

@joedolson
Copy link
Contributor

We're able to render blocks on the front-end statically; it seems like we should be able to mimic that in the editor, so that the HTML displays but is no longer editable. I like the idea suggested by @talldan of rendering to static markup; if we can find a good way to do that, it may be worth exploring. It fills the main need: disable editing while still allowing users to perceive the content.

@talldan
Copy link
Contributor

talldan commented Jul 18, 2024

I'm not sure it'd be feasible because of the issue I mentioned about rendering inner blocks within the templates. Also we can't be sure the markup won't need to be updated for particular changes (e.g. are there global styles changes that can cause the block markup to change?), but I put the idea out there to see if it sparked any ideas in others.

@ramonjd
Copy link
Member Author

ramonjd commented Jul 23, 2024

It's been a while since I looked at this issue, so I don't have all the knowledge/context.

I'm just riffing, but I wonder if there's a way to apply aria-disabled instead of inert and then capture all events on subtree. 🤔

I took a quick look and saw that the rich text block can be told about the block context's editing status:

https://github.com/WordPress/gutenberg/compare/try/replace-inert-on-disabled-editing-block-props

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 Accessibility Feedback Need input from accessibility Needs Decision Needs a decision to be actionable or relevant [Package] Components /packages/components [Type] Discussion For issues that are high-level and not yet ready to implement. [Type] Enhancement A suggestion for improvement. [Type] Question Questions about the design or development of the editor.
Projects
None yet
Development

No branches or pull requests

7 participants