Skip to content

aria-required-owned-element should not allow invalid children for having aria-busy#2387

Open
WilcoFiers wants to merge 1 commit intodevelopfrom
no-aria-busy-exception
Open

aria-required-owned-element should not allow invalid children for having aria-busy#2387
WilcoFiers wants to merge 1 commit intodevelopfrom
no-aria-busy-exception

Conversation

@WilcoFiers
Copy link
Member

@WilcoFiers WilcoFiers commented Feb 12, 2026

I've been looking over aria-busy, and I think we've been too permissive with it. Nowhere does ARIA actually say that if you put aria-busy on element that it can contain non-allowed children. What ARIA 1.2 said is that if an element is empty because content wasn't loaded yet authors must set aria-busy. This was has been pulled from ARIA 1.3 though, along with the rest of the required children section, because ARIA 1.3 now has allowed child roles. It doesn't mention aria-busy at all.

I think that allowing an aria-busy exception was a mistake, and that this "loading" example we have is invalid. aria-busy isn't intended to communicate a loading state. All it does is tell screen readers to wait in pronouncing live region changes because they aren't done. See also w3c/aria#2424

Need for Call for Review: 2 weeks, this breaks basically every automated implementation.


How to Review And Approve

  • Go to the “Files changed” tab
  • Here you will have the option to leave comments on different lines.
  • Once the review is completed, find the “Review changes” button in the top right, select “Approve” (if you are really confident in the rule) or "Request changes" and click “Submit review”.
  • Make sure to also review the proposed Call for Review period. In case of disagreement, the longer period wins.

…ing aria-busy

Removes the exception of elements with aria-busy, and moved an inapplicable example to failed.
@netlify
Copy link

netlify bot commented Feb 12, 2026

Deploy Preview for act-rules ready!

Name Link
🔨 Latest commit 26a096b
🔍 Latest deploy log https://app.netlify.com/projects/act-rules/deploys/698e16aae5094f00085561d1
😎 Deploy Preview https://deploy-preview-2387--act-rules.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Jym77
Copy link
Collaborator

Jym77 commented Feb 13, 2026

I'm not sure we do handle aria-busy correctly indeed, but I'm not sure about that PR either 🤔

  • ARIA 1.3 is indeed changing the "required" child to "allowed", clarifying intermediate generic and the likes. It will require us to revisit this rule (and maybe the one about parents too). But reading it, because intermediate generic are allowed, I'm not sure that <div role="menu">Loading</div> (without aria-busy) is an ARIA 1.3 failure (even wrapping the text in another <div>). I'm not sure the text node counts as an accessibility children. At least something like <div role="menu" aria-busy="true"> <img src="loading.gif" alt="Loading" /> </div> would make for a clearer case.
  • What is used in practice? The main problem here is not as much breaking implementations as breaking existing pages. If we suddenly decide that millions of web pages use wrong ARIA, I'd rather have that backed by a clear statement form ARIA group 😄
  • What is the correct way to indicate loading state to ATs? If the aria-busy way is not, what do we (and ARIA) ask authors to do? Should they change the role of the container during the loading stage? Or add a wrapper just to hold the aria-busy and loading indication. I can see how having the empty container already here can help visually, e.g. in providing some styling, … And why changing roles, or extra wrapper sounds like extra work.
  • What is the experience for ATs users? If the aria-busy trick works fine, I'm not sure we have a good reason to change it.
  • Finally, there is also the point of "minimum certainty": we are certain that this is a problem without aria-busy, less sure with aria-busy, so we could keep the rule as is, adding a note in that sense (and maybe remove the aria-busy example, leaving implementers decide for themselves on that). Not super good in terms of harmonization, but until we get clarification from ARIA group, that might be the simplest way.

All in all, I think we will need to drastically revisit this rule for ARIA 1.3 (due to the required/allowed change), so we should maybe wait for this 🤔 (or start writing an ARIA 1.3 rule on the side given it will be quite different).

I won't oppose this change. I'm more concerned about the impact on actual pages (that we now declare as "bad") than about the impact on implementation (it's a fairly small change to do).

@WilcoFiers
Copy link
Member Author

@Jym77 I think the problem is worse with aria-busy than without. aria-busy tells AT that the element isn't done, and that they may choose to ignore changes to it until it's no longer set to busy. So if you put aria-busy on a loading message, that means AT may (and do) ignore it. A loading state is a status message, that's a 4.1.3 status message failure on top of the malformed accessibility tree issue.

I don't think it's an "ARIA isn't clear if this is allowed" case. ARIA doesn't say it's allowed, so it isn't. That thee's no text role in ARIA (anymore) doesn't mean text is exempt, just like native date pickers aren't exempt. Those are child nodes, with a role not on the allowed child roles list.

As for us changing our minds and failing things that we previously said didn't... that happens. I don't think this is a change that will affect a lot of pages. I've only ever recall seeing one of them, and that is one that I would have failed for using aria-busy in a manual audit.

@Jym77
Copy link
Collaborator

Jym77 commented Feb 13, 2026

I don't think it's an "ARIA isn't clear if this is allowed" case. ARIA doesn't say it's allowed, so it isn't. That thee's no text role in ARIA (anymore) doesn't mean text is exempt, just like native date pickers aren't exempt. Those are child nodes, with a role not on the allowed child roles list.

I'm referring to the definition of Accessibility child (used in "allowed children") that ignores "elements of role generic or none intervening [between the parent and the children]." And has explicit allowed example of <div role="list"> <div> <div role="listitem"> </div> </div> </div>.

Now, I am not sure whether <div role="list"> <div> </div> </div> would be allowed or not. The inner div is a generic, so not one of the allowed children roles. But the accessibility child definition specifically skips over generic. But it doesn't mention "generics without any accessibility node inside". (and the definitions in 7. Accessibility Tree mention only elements, not text nodes, if I'm quick reading it correctly)


Fair points otherwise 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants