html icon indicating copy to clipboard operation
html copied to clipboard

Connect HTML spec up to new CSS `interactivity` property

Open mfreed7 opened this issue 11 months ago • 29 comments

This PR makes the following changes to "inertness":

  1. Remove duplication - allow the CSS spec to define the concept of "inert", and the associated behaviors (pointer events, text selection behavior, etc.).
  2. Make the inert HTML attribute set interactivity:inert via a new UA stylesheet rule.
  3. Make inertness "sticky" so that sub-trees cannot de-inert content.
  4. Make modal dialogs non-inert via an interactivity:auto UA stylesheet rule, and special logic that exempts the dialog from the prohibition on de-inerting.
  5. {later} A rule likely needs to be added for fullscreen elements also, setting :fullscreen {interactivity: auto}.

CSS spec is here: https://drafts.csswg.org/css-ui-4/#inertness


  • [X] At least two implementers are interested (and none opposed):
    • Chromium is supportive/driving
    • Gecko is supportive
  • [X] Tests are written and can be reviewed and commented upon at:
    • https://wpt.fyi/results/css/css-ui?label=master&label=experimental&aligned&q=interactivity-
  • [X] Implementation bugs are filed:
    • Chromium: https://crbug.com/370065759
    • Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1949843
    • WebKit: https://bugs.webkit.org/show_bug.cgi?id=288202
  • [X] Corresponding HTML AAM & ARIA in HTML issues & PRs: not needed, per https://github.com/whatwg/html/pull/10956#issuecomment-2731261954
  • [X] MDN issue is filed: https://github.com/mdn/mdn/issues/640
  • [X] The top of this comment includes a clear commit message to use.

(See WHATWG Working Mode: Changes for more details.)


/indices.html ( diff ) /infrastructure.html ( diff ) /interaction.html ( diff ) /interactive-elements.html ( diff ) /rendering.html ( diff )

mfreed7 avatar Jan 28 '25 00:01 mfreed7

I think blocked by a modal dialog should be defined in terms of interactivity (either set as a presentational hint on the root, or using an UA stylesheet rule), because otherwise dialog:modal { interactivity: auto } won't do anything (because auto is the default value. I don't think this is what the current HTML spec PR does.

nt1m avatar Jan 30 '25 00:01 nt1m

I think blocked by a modal dialog should be defined in terms of interactivity (either set as a presentational hint on the root, or using an UA stylesheet rule), because otherwise dialog:modal { interactivity: auto } won't do anything (because auto is the default value. I don't think this is what the current HTML spec PR does.

I added a Note about this. But I think the concept (agreed to over in CSSWG I believe) was that both specs can set something to be inert. The problem with defining modal dialog behavior in terms of CSS is that it allows author CSS to make parts of the page "un-inerted", which is undesirable. And it can't be set to interactivity:inert/auto !important to avoid that problem, because then that doesn't allow the author to "re-inert" the dialog itself.

mfreed7 avatar Jan 30 '25 00:01 mfreed7

I think blocked by a modal dialog should be defined in terms of interactivity (either set as a presentational hint on the root, or using an UA stylesheet rule), because otherwise dialog:modal { interactivity: auto } won't do anything (because auto is the default value. I don't think this is what the current HTML spec PR does.

I added a Note about this. But I think the concept (agreed to over in CSSWG I believe) was that both specs can set something to be inert. The problem with defining modal dialog behavior in terms of CSS is that it allows author CSS to make parts of the page "un-inerted", which is undesirable. And it can't be set to interactivity:inert/auto !important to avoid that problem, because then that doesn't allow the author to "re-inert" the dialog itself.

Another issue is that no one's been able to come up with UA styles that actually works with shadow DOM.

lilles avatar Jan 30 '25 09:01 lilles

LGTM with nits. This turned out pretty nice; thanks for iterating!

Let me know when the checkboxes in the OP are filled out.

Thanks for the review!

  • [ ] At least two implementers are interested (and none opposed):

@annevk @emilio would you mind please providing support for landing this?

mfreed7 avatar Feb 21 '25 17:02 mfreed7

@scottaohara @aleventhal does this need any change to the HTML AAM spec? This PR (to HTML) doesn't actually change the behavior of existing things like inert or modal dialogs. The CSSWG spec change (which already landed, here) might need something?

mfreed7 avatar Feb 21 '25 17:02 mfreed7

What is the status of this in the CSS WG? It's relatively straightforward to get things in drafts, but that historically hasn't really conveyed any kind of stability.

annevk avatar Feb 24 '25 15:02 annevk

What is the status of this in the CSS WG?

In terms of the CSSWG's process (which follows W3C practices), it is in an editor's draft. There have been multiple CSSWG consensus resolutions, such as to add it and decide on behaviors like interaction with the top layer.

chrishtr avatar Feb 28 '25 18:02 chrishtr

What is the status of this in the CSS WG?

In terms of the CSSWG's process (which follows W3C practices), it is in an editor's draft. There have been multiple CSSWG consensus resolutions, such as to add it and decide on behaviors like interaction with the top layer.

But (IMO) we should not consider anything in CSSWG drafts as stable until there is at least a prototype and some tests. Lack of unresolved issues before that happens does not mean much

astearns avatar Mar 06 '25 16:03 astearns

But (IMO) we should not consider anything in CSSWG drafts as stable until there is at least a prototype and some tests. Lack of unresolved issues before that happens does not mean much

Just to put it here, Blink has implemented this property, and written the WPTs:

https://wpt.fyi/results/css/css-ui?label=master&label=experimental&aligned&q=interactivity

mfreed7 avatar Mar 06 '25 16:03 mfreed7

The CSS Working Group just discussed Connect HTML spec up to new CSS `interactivity` property.

The full IRC log of that discussion <past> https://github.com/whatwg/html/pull/10956
<hdv> masonf: quick intro… this is two sets of specs (CSS, HTML) for a new property called `interactivity`, works like `inert` in HTML, there's a spec PR in HTML that connects this up
<hdv> masonf: both sides have some control here… HTML has a way to make things inert, CSS does too now, HTML can interconnect the two
<hdv> masonf: and make sure overriding works as expected
<hdv> masonf: this was editorially reviewed, am looking for implementor support
<hdv> masonf: for both parts, HTML and CSS
<lwarlow> q+
<emilio> q+
<hdv> annevk: what i'd like input from CSSWG… atm we take something with dep on HTML spec, it's the equivalent to CR spec in W3C land, taking a dependency in your work, if it breaks something you're invalidating implementations
<hdv> fantasai: if something is in CR, it's def very stable. If not, it's not clear where it is in terms of stability
<hdv> fantasai: we do have CSS snapshots, to show where things are
<hdv> fantasai: also have availability to show 'these things are not in CR but stable enough to ship'
<hdv> fantasai: kind of the only tool we have to indicate stability beyond CR flag
<hdv> fantasai: sometimes a feature was worked on by one team but others haven't seen it yet, that convo prompts people to look at it and they might find design issue or issues that weren't paid attention to
<hdv> fantasai: if you want something at the level of super stable, we can have that conversation
<hdv> ack luke
<hdv> ack lw
<hdv> lwarlow: the propery name seems ambiguous
<hdv> s/propery/property
<hdv> lwarlow: makes me feel iffy re: what it wants to do in the future and if this naming allows it
<hdv> lwarlow: maybe interactivity is clearer and I haven't read enough… interactivity doesn't _just_ mean is it inert or not… eg see focusability… there's a desire to have a CSS way to cover focusability, is that part of it or separate?
<hdv> ack em
<hdv> emilio: one of the comments on the PR was re the model
<hdv> emilio: it feels iffy to deal with some things via CSS and with others, have it automatic, like auto
<hdv> emilio: makes it a bit harder to reason about
<masonf> q+
<hdv> emilio: if you're fine with that, seems fine implementation wise
<past> ack masonf
<fantasai> s/availability to show/capability in Snapshot to show for individual features,/
<hdv> masonf: pretty strong push from the a11y folks, reason the value is auto is… for somebody to be able to do body { /* set it to auto */ } would break all sorts of accessibility
<hdv> emilio: there are other ways to do that… eg you could set important but would be annoying
<hdv> emilio: if the spec could make that clearer, eg this is weird but this is why it is weird, would be ok. It's a bit annoying implementation wise, but it's okay
<hdv> emilio: no concerns
<hdv> masonf: can't really use !important either, you need to be able to re-inert a modal dialog via CSS
<hdv> emilio: yes is weird
<hdv> emilio: right now, webkit effectively has inheriit bit in the style object, basically an internal property
<hdv> emilio: now, with a value on top of that… doesn't inert in HTML have similar concert?
<hdv> s/concert/concerns
<hdv> masonf: but then it's a developer side thing, modals are a bit more special I guess
<hdv> emilio: not sure if I agree but its ok
<hdv> masonf: just parroting what I've heard
<hdv> panos: so this room's concensus is this is ok to move forward with?
<hdv> emilio: I'm okay with that
<hdv> olli: if you make something inert and focus is in that area, what happens to the focus?
<hdv> emilio: same as if you make it visibility hidden or something else
<hdv> annevk: what did you mean with move forward?
<hdv> panos: is everyone ok with CSS side of things?
<hdv> masonf: comment on weird side of things probably belongs in HTML
<hdv> annevk: Luke brought op the name of the property, that seems essential for both specs
<hdv> annevk: and we probably need good idea of what stability means on the CSS side
<hdv> annevk: at TC39 we know stability/consensus within the group; it'd be trivial to organise the HTML stuff around that, but in CSS it's less clear
<past> q?
<hdv> fantasai: I think we can make it more clear,doing it more rigorously?
<fantasai> s/doing it/just need to use Snapshot/
<hdv> masonf: does TC39 refer out to other specs and if so how? what we're discussing here is interdepencies of specs?
<hdv> annevk: how?
<hdv> masonf: release process was independent in the past
<hdv> annevk: at TC39 usually have dependencies but one way, we know at which point it has a state where TC39 is happy about it
<hdv> annevk: we want to avoid building on quicksand in this situation
<hdv> past: is it okay for CSS WG to discuss internally and give out a signal that WHATWG can use as a stability indicator?
<hdv> astearns: personally I think we should be careful about referencing something in a CSS spec assuming it is stable
<hdv> astearns: lack of issues is one thing, usually issues come up when people try implementing something. I don't think this property has prototypes yes
<hdv> masonf: it's fully implemented in Chromium and there are WPTs
<hdv> astearns: in that case my concern is less, may be stable enough to reference
<hdv> fantasai: I think it should be put in a snapshot… changes may happen due to more people looking at it… putting it into a snapshot could be a way to get people to chime in
<fantasai> https://www.w3.org/TR/css/#CR-exceptions
<hdv> astearns: we also had things ready to ship even if not ready completely yet
<hdv> past: any other thoughts or feedback?
<hdv> past: this seems like a question for CSSWG to answer
<astearns> s/even if not/even if the whole module is not/
<fantasai> s/may happen/happen in response to implementation, but also in response to/
<hdv> past: sounded like you were waiting for implementor feedback, masonf ?
<hdv> masonf: yes
<hdv> emilio: without my mozilla hat on, sounds good to me
<hdv> olli: I need to review the PR

css-meeting-bot avatar Mar 06 '25 16:03 css-meeting-bot

Given what we discussed today this looks good to me, but we should make very clear that the "make modal dialogs not overridable, but inert attribute overridable" is intentional.

emilio avatar Mar 06 '25 16:03 emilio

Given what we discussed today this looks good to me, but we should make very clear that the "make modal dialogs not overridable, but inert attribute overridable" is intentional.

Great, thanks! I've checked the checkbox in the OP based on this comment.

I also added a paragraph of more motivation for the "weird" behavior. LMK what you think.

mfreed7 avatar Mar 06 '25 17:03 mfreed7

All the boxes here looked checked, but agreement is fresh off the presses and maybe people want to review the new note.

We haven't gotten an answer back on whether this affects HTML-AAM / ARIA, but I am pretty sure it doesn't since there's no new HTML attributes or elements involved.

I'll plan on merging this mid-next-week, assuming @mfreed7 addresses my nit and rebases on master to resolve conflicts by then.

domenic avatar Mar 07 '25 02:03 domenic

No, this cannot merge. The CSS side still has open issues and the CSS WG has not indicated this is stable to reference.

annevk avatar Mar 07 '25 07:03 annevk

We don't have any items in our working mode for "the CSS side has open issues" or blocking on W3C process. I believe we meet all the criteria in https://whatwg.org/working-mode#additions and https://whatwg.org/working-mode#changes . Can you point to which one is not met?

domenic avatar Mar 07 '25 09:03 domenic

https://github.com/w3c/csswg-drafts/issues/11849 is Luke's issue (for cross-referencing purposes)

emilio avatar Mar 07 '25 10:03 emilio

We haven't gotten an answer back on whether this affects HTML-AAM / ARIA, but I am pretty sure it doesn't since there's no new HTML attributes or elements involved.

I'm pretty sure too, but @scottaohara did mention to me yesterday that he'd take a look at this soon. I'm ok waiting for that, just to confirm.

I'll plan on merging this mid-next-week, assuming @mfreed7 addresses my nit and rebases on master to resolve conflicts by then.

Ok, I addressed the nit, and rebased. The rebase wasn't super clean, given the dialog closedby changes, but I think I got it fixed up correctly. An extra pair of eyes wouldn't hurt.

mfreed7 avatar Mar 07 '25 17:03 mfreed7

This is really disappointing to see. I thought the discussion on https://github.com/whatwg/html/issues/10811 was really promising.

alice avatar Mar 17 '25 03:03 alice

This is really disappointing to see. I thought the discussion on #10811 was really promising.

Sorry to hear that. The discussion on #10811 was hypothetical and (I think?) could still be moved forward if we wanted to. It describes a way to have explicit exceptions for other top layer things like popovers while there's a modal dialog open. My understanding from several comments on that issue was that this situation wasn't desirable from an a11y perspective, so this PR didn't change the modal dialog behavior. Can you comment? E.g. this comment mentions that this might violate screen reader assumptions, and the comments about re-parenting things in the a11y tree scared me a bit. Perhaps those aren't as scary as they sound?

mfreed7 avatar Mar 17 '25 23:03 mfreed7

from what i can tell, reading this PR over a few times now, is that i don't see anything in here that would necessarily need to be changed in the HTML AAM or CORE AAM specs - unless there are mappings that were altered that wouldn't be called out in this HTML spec update?

As I mentioned in my initial comment about the use cases i had for allowing something to escape inertness - I wasn't wedded to the idea that it needed to be done via CSS. I'm not against it, but I'm also not a strong supporter of it being the solution here.

The back and forth with Alice in #10811 seemed promising - specifically allowing popovers to escape inertness, and then essentially adjusting them in the a11y tree - much like aria-owns does - to make it seem to people using AT that the popover was a child of the current modal dialog.

So, I guess with all that said, I'm not sure about allowing for inertness to be escaped if we already have one potential solution which would arguably be a lot safer / better for the end user experience. For my other use cases, while I still think they're valid, I think it's probably a better idea to see if there aren't other potential solutions, than introducing an inert escape hatch that can never be closed once open. Because use cases aside, @alice is right that this could be problematic if unchecked. If this PR can go through without the ability to uninert things for now, that'd be the safer option, imo.

scottaohara avatar Mar 18 '25 00:03 scottaohara

It describes a way to have explicit exceptions for other top layer things like popovers while there's a modal dialog open.

That's not how I had envisioned it. The way I proposed and understood it (and it seemed like you agreed) was that it would both explain how dialogs and fullscreen elements made the rest of the page inert, and fix the issue with content in a top layer on top of dialogs being made inert erroneously.

It would also open the door to exploring better ways to implement custom modal UI without the need to use <dialog> or inert (and thus with no need to add the capacity to escape inert here).

E.g. this comment mentions that this might violate screen reader assumptions, and the comments about re-parenting things in the a11y tree scared me a bit. Perhaps those aren't as scary as they sound?

Those are implementation details needed to make the a11y tree semantics match the dialog semantics, and would be needed regardless (i.e. if the browser didn't do this, the author using popover with either a <dialog> or any custom dialog which used role=dialog would have to, and they most likely wouldn't know to).

alice avatar Mar 18 '25 04:03 alice

i'm currently looking at the mdn draft for the customizable select, and in it a passing comment was mentioned that the inert button part of the select could have its inertness undone using the CSS interactivity property. That button part was made inert on purpose. The HTML AAM mappings specifically call it out as inert and that as far as the a11y tree is concerned, the select/button part should not be perceived as two separate elements to end users - why would authors be allowed to undo that with CSS?

scottaohara avatar Mar 18 '25 14:03 scottaohara

I'm catching up here and in #10811 and wanted to add a few thoughts --

I think the idea of a CSS opt-out of inert makes me nervous, especially one that differs in behavior depending on what has made the element is inert (i.e. because of an ancestor style vs. a modal dialog). In practice, in a dev environment with code contributions from many different teams (as in any medium-to-large organization), it's easy to have controls from different sources using different methods to inert background content. One dialog might easily be an HTML <dialog>, and another a custom dialog component using inert or the new CSS style. Or, as in the case of the UI library I work on, we might do things like convert our shipped Dialog control from a custom solution to one using <dialog> in a version update.

In that environment, if another control (e.g. a notification popup) sets the interactivity style, that would be exceedingly frustrating to debug and maintain since it might work with some dialogs but not the others. Conversely, a control that incorrectly sets interactivity: auto would still work fine with a <dialog> element but not the custom control. This difference in behavior would, in my opnion, make the style effectively verboten since you (a theoretical component dev) can't control or predict how it'll behave re: other inerting controls on the page that you have no control over. I also don't really think it's reasonable to expect regular non-standards-participating developers to understand the distinction between HTML dialog inert-ness and CSS inert-ness in practice.

There's also the issue that exempting modal dialogs from being able to be escaped does away with the most common use cases mentioned so far. Going back to @scottaohara's examples, two of the three would require being able to escape dialogs.

So having said all that, the reason I think I'm opposed to adding any inert escape via CSS rather than having CSS also escape dialogs is:

  • Providing screen reader access to controls outside a modal dialog is more complicated than just putting them in the accessibility tree. Multiple screen readers either hard- or soft-restrict the cursor to an open dialog, so even if something else were escaped and in the a11y tree, it still wouldn't necessarily be reachable. VoiceOver is the strictest about this I believe, and won't even expose live region changes outside of a dialog, even if they are in the a11y tree. This is essentially what I was chatting with Alice about earlier, which she referenced in this comment
  • Having any control on the page able to escape being inert-ed by an open dialog based on style specificity just feels like opening the door to chaos. It introduces a war between different elements trying to make their inert styles win out, essentially moving the accessibility aspect of top-layer management into CSS.

I really like the suggestion made in #10811 around re-parenting other top-layer nodes into a dialog (at least for the top-layer nodes that are on top of the dialog), and having that be the "escape" for inert. That seems both much easier to manage for web authors, and also much less of a hidden foot-gun for accessibility. It does seem like both this potential approach and other options for escaping inert need more exploration before landing on one, though.

TL;DR: inert is such a powerful tool for either helping or destroying accessibility that combining it with an authoring experience that is hard to understand and easy to misuse seems like a recipe for disaster.

smhigley avatar Mar 18 '25 21:03 smhigley

Hi, I’ve tried below to answer all questions. Because there were many, this got quite long. Apologies for length or if I missed anything!

from what i can tell, reading this PR over a few times now, is that i don't see anything in here that would necessarily need to be changed in the HTML AAM or CORE AAM specs - unless there are mappings that were altered that wouldn't be called out in this HTML spec update?

Great! Thanks for that - based on this comment I’ve checked the last box on this PR.

As I mentioned in my initial comment about the use cases i had for allowing something to escape inertness - I wasn't wedded to the idea that it needed to be done via CSS. I'm not against it, but I'm also not a strong supporter of it being the solution here.

I agree there are use cases - e.g. a “user space” modal dialog that doesn’t utilize the top layer. Currently, that’s typically implemented using manual focus trapping, which is worse for a11y and correctness.

The back and forth with Alice in #10811 seemed promising - specifically allowing popovers to escape inertness, and then essentially adjusting them in the a11y tree - much like aria-owns does - to make it seem to people using AT that the popover was a child of the current modal dialog.

My concerns are twofold: First, I wonder if the better “solution” to that problem is to require developers to simply nest the popover within the dialog. That provides out-of-the-box inertness and a11y. Second, I worry about the implementability of making the a11y tree not match the DOM tree in such a significant way. I know that Blink has had a long series of bugs related to situations like this, and we’d like to avoid more of them. + @aleventhal for comments based on experience here.

I think it's probably a better idea to see if there aren't other potential solutions, than introducing an inert escape hatch that can never be closed once open.

Are there other solutions that are better? It seems that the crux of the issue isn’t really the shape of how something gets un-inerted, but more that it can be un-inerted at all.

If this PR can go through without the ability to un-inert things for now, that'd be the safer option, imo.

Technically, this PR doesn’t add un-inerting behavior (that behavior is in the CSS spec). On the contrary, this PR goes to some length to preserve the existing behavior wherein modal dialog related inertness cannot be un-inerted.

That's not how I had envisioned it. The way I proposed and understood it (and it seemed like you agreed) was that it would both explain how dialogs and fullscreen elements made the rest of the page inert, and fix the issue with content in a top layer on top of dialogs being made inert erroneously.

It would also open the door to exploring better ways to implement custom modal UI without the need to use <dialog> or inert (and thus with no need to add the capacity to escape inert here).

Can you help me understand your approach a bit better? Reading your comment and the ones below, it seems to just say that modal dialogs form a “blocking” top layer item, which un-inert the things above them in the stack, and inert everything below them. That still feels like magic (i.e. it doesn’t explain in the sense of other developer-visible APIs) and also requires the use of the dialog element and the UA-provided top layer. I.e. it doesn’t allow userspace modals that aren’t in the top layer. Please help me understand my disconnect.

Those are implementation details needed to make the a11y tree semantics match the dialog semantics, and would be needed regardless (i.e. if the browser didn't do this, the author using popover with either a <dialog> or any custom dialog which used role=dialog would have to, and they most likely wouldn't know to).

One nice thing about the existing behavior of popovers and modal dialogs is that it in fact does require the developer to properly nest the popover within the dialog, or it’ll be inert and won’t work. I’m concerned about making the implementation of the a11y more convoluted, for fear of introducing major bugs and crashes and things, which aren’t good for users.

i'm currently looking at the mdn draft for the customizable select, and in it a passing comment was mentioned that the inert button part of the select could have its inertness undone using the CSS interactivity property. That button part was made inert on purpose. The HTML AAM mappings specifically call it out as inert and that as far as the a11y tree is concerned, the select/button part should not be perceived as two separate elements to end users - why would authors be allowed to undo that with CSS?

This was simply a general effort to avoid !important on the UA stylesheet for customizable-<select>. There might be uncommon use cases where the button wants to be made back into a button, hopefully with careful consideration of a11y and use of ARIA. But I would consider this a fairly corner case, and not likely to be hit by developers on accident or without noticing.

I think the idea of a CSS opt-out of inert makes me nervous, especially one that differs in behavior depending on what has made the element is inert (i.e. because of an ancestor style vs. a modal dialog). In practice, in a dev environment with code contributions from many different teams (as in any medium-to-large organization), it's easy to have controls from different sources using different methods to inert background content. One dialog might easily be an HTML <dialog>, and another a custom dialog component using inert or the new CSS style. Or, as in the case of the UI library I work on, we might do things like convert our shipped Dialog control from a custom solution to one using <dialog> in a version update.

So I think one nice thing about the current PR is that the mechanism for un-inerting is always the same: interactivity: auto. That’s true whether the inertness was provided by the inert attribute or interactivity: inert. Of course, the one exception is modal <dialog>s, and that exception was preserved precisely and only to maintain the a11y guarantees that it already provides.

In that environment, if another control (e.g. a notification popup) sets the interactivity style, that would be exceedingly frustrating to debug and maintain since it might work with some dialogs but not the others. Conversely, a control that incorrectly sets interactivity: auto would still work fine with a <dialog> element but not the custom control. This difference in behavior would, in my opnion, make the style effectively verboten since you (a theoretical component dev) can't control or predict how it'll behave re: other inerting controls on the page that you have no control over. I also don't really think it's reasonable to expect regular non-standards-participating developers to understand the distinction between HTML dialog inert-ness and CSS inert-ness in practice.

I think I need more help understanding the problematic cases here. Basically, there seem to be two types of interaction implementations: one in which modal <dialog> elements are used, and another where they aren’t. In the former case, those modal dialogs will always do the right thing - they’ll be non-inert while the rest of the page is inert. In the latter case, it’ll be up to the site to properly inert and un-inert the page and the “dialog”, regardless of the mechanism used for “inert”. If it’s the platform, they’ll have to get their interactivity properties set up correctly. If it’s totally user-space, they’ll have to make sure their JS code that handles focus trapping is done correctly. There is a potential for footguns in either approach. But I don’t think it helps to always require userspace modal implementations to also build their own focus trapping. That would seem to create two footguns rather than one, wouldn’t it?

There's also the issue that exempting modal dialogs from being able to be escaped does away with the most common use cases mentioned so far. Going back to @scottaohara's examples, two of the three would require being able to escape dialogs.

I agree, use cases 2 and 3 there would not be able to use a native modal <dialog> element, and would instead need to use the interactivity property to inert and de-inert the proper elements.

So having said all that, the reason I think I'm opposed to adding any inert escape via CSS rather than having CSS also escape dialogs is:

Oh, I guess you are supportive of escaping the inertness of modal-<dialog>. Can you please confirm?

  • Providing screen reader access to controls outside a modal dialog is more complicated than just putting them in the accessibility tree. Multiple screen readers either hard- or soft-restrict the cursor to an open dialog, so even if something else were escaped and in the a11y tree, it still wouldn't necessarily be reachable. VoiceOver is the strictest about this I believe, and won't even expose live region changes outside of a dialog, even if they are in the a11y tree. This is essentially what I was chatting with Alice about earlier, which she referenced in this comment

Help me understand - this sounds like a reason not to allow escaping modal <dialog> inertness.

  • Having any control on the page able to escape being inert-ed by an open dialog based on style specificity just feels like opening the door to chaos. It introduces a war between different elements trying to make their inert styles win out, essentially moving the accessibility aspect of top-layer management into CSS.

I guess same question as above - this sounds like a reason not to allow escaping.

TL;DR: inert is such a powerful tool for either helping or destroying accessibility that combining it with an authoring experience that is hard to understand and easy to misuse seems like a recipe for disaster.

This is a good thing to be concerned about. I think the documentation needs to be clear. And to me, these three points encapsulate the behavior:

  1. Modal dialogs make the page inert, and the dialog contents non-inert. This behavior cannot be overridden.
  2. The inert attribute simply sets interactivity: inert on the element.
  3. The interactivity property can be used to set an element and its descendants to be inert (interactivity: inert) or un-inert (interactivity: auto).

While it’s three bullets instead of one, it still feels fairly understandable to me.

mfreed7 avatar Mar 20 '25 21:03 mfreed7

I wonder if the better “solution” to that problem is to require developers to simply nest the popover within the dialog.

To clarify, does that mean you now support my proposal that popovers outside of the currently showing modal <dialog> should not be rendered on top of it?

I would still be fine with that, and I agree it gets around having to write more complicated code for the accessibility tree. That would still mean that use case doesn't justify the inert-escaping behaviour that's being pushed here.

Can you help me understand your approach a bit better? Reading your comment and the ones below, it seems to just say that modal dialogs form a “blocking” top layer item, which un-inert the things above them in the stack, and inert everything below them. That still feels like magic (i.e. it doesn’t explain in the sense of other developer-visible APIs) and also requires the use of the dialog element and the UA-provided top layer.

It explains in the sense that it ties un-inerting to a lower-level concept, the top layer, rather than being specific to the <dialog> element. That would mean that other ways to add things to the top layer, including popover and any other future features which use the top layer, could easily be modified to allow inerting behaviour. Unlike the current language, it doesn't require <dialog> necessarily.

What it does do, unlike this proposal, is inherently tie "everything-else-inerting" to a visual indication that content is non-interactive. Content in the top layer, particularly a top layer with a backdrop style, visually obscures content in lower layers.

it doesn’t allow userspace modals that aren’t in the top layer.

I'm fine with that. Obviously, any page-level modal should be in the top layer anyway, so that it doesn't conflict with other top layer elements.

"Component modals" seem to be doing a lot of heavy lifting at this point as a justification for this API. Is that really a user need so urgent we can't, as Scott suggested, take a moment to look at alternatives? Are we really that sure, even, that this API is a good solution for those? Were any alternatives explored at all for that problem?

(Oh, sorry, UI tours too. Same comments apply.)

Technically, this PR doesn’t add un-inerting behavior (that behavior is in the CSS spec). On the contrary, this PR goes to some length to preserve the existing behavior wherein modal dialog related inertness cannot be un-inerted.

It does add un-inerting behaviour for the inert attribute, though. Besides, the CSS PR already landed, so it seems unlikely any comments there would be addressed.

This is a good thing to be concerned about. I think the documentation needs to be clear.

I think you have a lot more faith in developers to read and absorb accessibility guidance than I do. The unfortunate reality is that a significant number of developers won't consider accessibility concerns at all, much less take the time to read the documentation. If it looks good, that's what ships. We can't fix that problem across the board, but we can at least do our best to avoid footguns that are almost certain to harm users.

@scottaohara, @smhigley and I are all advocating not rushing into this API, and you've acknowledged at least some of these concerns as valid. Please don't misconstrue this as a simple request for additional documentation.

alice avatar Mar 21 '25 06:03 alice

https://jsfiddle.net/056qswnh/ - take this demo for example (relies on chrome 135), clicking on the popover above the dialog's button triggers that button, despite a popover visually being on top. Clicking outside the popover closes the popover but not the light dismissable dialog, despite the fact all other pointer events get swallowed down to the dialog?

I just don't know how to explain this behaviour. Using interactivity also doesn't solve this problem nor explaining of the behaviour. Meanwhile if I have a custom modal dialog I can easily set interactivity: auto on the popover and it just work. Are we just going to prolong the situation where people use custom modal implementations rather than native dialog?

I agree that if a popover is opened in the top layer above the dialog but is inert it shouldn't render. Else you end up with a very confusing user experience.

I wonder if the better “solution” to that problem is to require developers to simply nest the popover within the dialog. That provides out-of-the-box inertness and a11y.

One other possibility of an escape hatch would be based on the popovers invoker DOM location. IIRC the location of the popover doesn't really matter for anything else in the popover API (e.g. nesting behaviour). If the invoker is a dialog child perhaps that's enough of a signal that actually that popover should work correctly even though it's outside the dialog in the DOM?

For the cases like toasts where there isn't a trigger element, you could still do something like .showPopover({source: dialog}) to get that escape hatch?

That is if we didn't want to just do this magically for all popovers opened after a dialog is (and thus being above it in the top-layer). I'm unaware of the potential implementation complications but the fact we already do focus order changes based on the invoker suggests we could do other such changes?

Now I'm not saying allowing people to uninert modal dialogs whenever they want is a good thing. But if they can do common things for their custom dialog (or by using a non-modal dialog that they then hijack into a "modal") but not with the built-in it feels like another reason people would not use the built-in. That's a shame given all the hardwork that's gone into making real dialogs great (command/commandfor, close watchers, optional light dismiss etc).

If we could build these escape hatches into the system it would be good. Now I realise some of this is tangential to the point of this PR but the new author control does introduce a new angle to look at this.

lukewarlow avatar Mar 21 '25 13:03 lukewarlow

some quick responses:

  • it is a good thing that modal dialog intertness cannot be undone with CSS interactivity.
  • per the popover / modal dialog use case - just making the popover escaping inertness would not be enough to solve the use case. it would also have to become an accessibility child of the modal dialog to meet user expectations. i hope these two points clarify any ambiguity over what people expect. aka - modal inertness should not be able to be undone with css.
  • i am happy to see that the UA stylesheet for customizable select was updated so that a web author could not undo the button part's inertness.

scottaohara avatar Mar 21 '25 22:03 scottaohara

Some less quick responses :D:

To @mfreed7's questions:

Oh, I guess you are supportive of escaping the inertness of modal-

.

and

Help me understand - this sounds like a reason not to allow escaping modal

inertness.

More directly, I do not think escaping inertness is a good idea for the reasons Alice and Scott outlined more eloquently.

I do think there are some valid use cases to address that involve components outside modals needing to be user-accessible (e.g. a toast notification center). However, I don't think a direct inert escape hatch is the best approach; instead, I think it needs more brainstorming.

One of the things I was trying to get at earlier in a roundabout way is that the primary use case for having interactivity: auto escape inertness is specifically for controls that need to escape modal dialogs. Since it isn't a good idea to support that, I don't really see a compelling reason to have this at all, especially since it comes with significant drawbacks and foot-guns.

smhigley avatar Apr 05 '25 10:04 smhigley

Per the comments above, and the recent resolution from the CSSWG/WHATWG/OpenUI joint meeting, I've updated this PR to disallow de-inerting. The only thing that remains de-inertable is the topmost modal dialog.

mfreed7 avatar May 15 '25 16:05 mfreed7