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

[css-contain-2][inert]: inert and hidden containments should share common logic #7703

Open
clshortfuse opened this issue Sep 6, 2022 · 5 comments
Labels
css-contain-2 Current Work privacy-needs-resolution Issue the Privacy Group has raised and looks for a response on.

Comments

@clshortfuse
Copy link

clshortfuse commented Sep 6, 2022

I'm talking about these two specifications:

https://html.spec.whatwg.org/multipage/interaction.html#inert

https://drafts.csswg.org/css-contain/#skips-its-contents

inert seems very similar to the conditions for [css-contain] skip its contents. It seems as though these terms may be able to joined. It may also allow expression of inertness over CSS rules with something like container-visibility: inert.

The reason behind this is because when HTMLDialogElement.showModal() was implemented, none of the optimizations as we see in container-visibility were available at the time. All modern browsers (eg: Chrome, FireFox, Safari and Edge) all perform heavy restyle calculations on #document. This is likely because inert will update interactive elements as :disabled. This causes real-world implementation of HTMLDialogElement.showModal() to be questionable. If showModal() will guarantee frame drops on average sized DOM heavy pages on average consumer devices, then it's unlikely to be adopted in practice. If browsers are to target this performance issue, being able to use the already optimized procedure of container-visibility may prove helpful.

The challenges between both are figuring things such as:

  • Are inert elements hidden from accessibility or not? If they are, then hidden containments share this as well. See: Inert subtree section is missing requirement that it should NOT be exposed to accessibility whatwg/html#7796
  • Should inert elements have language to explicitly skip tab-order?
  • If find-in-page not being available for content-visiblity: hidden is a requirement, should it also be a requirement of inert, instead of its current state of optional?
  • Inert enforces a disabled state for certain elements. Should this also apply to elements inside hidden containments (which aren't focusable or selectable by spec)? If an interactive element is within a hidden containment, how does a dev detect this over JS, if at all?

Some solutions:

  • Relax inert to update elements as disabled (remove tree-walking)
  • Enforce [inert] to be reflected as an attribute, allowing CSS styles calculations
  • Create a new term for "not-focusable", "exclude from tab-order", "exclude from find-in-page" and have both inert and css-contain reference that.
  • Change nothing in spec and let each user agent decide best procedure for implementing inert optimally, if at all.
@Loirooriol
Copy link
Contributor

I don't see how inert and content-visibility: hidden are similar. Seem completely different to me.

The optimizations for content-visibility: hidden won't apply to inert just because both are exclude from find-in-page, etc. content-visibility: hidden can avoid laying out its contents, inert can't.

BTW, https://drafts.csswg.org/css-contain/#cv-a11y says that contents of content-visibility: hidden should be omitted in the accessibility tree. And inert elements are not a suitable sequentially focusable area, so you can't reach them by sequential navigation.

@clshortfuse
Copy link
Author

clshortfuse commented Sep 7, 2022

@Loirooriol I'm tracking the performance issues with Chrome here:

https://bugs.chromium.org/p/chromium/issues/detail?id=1360404
Which might help explain where I'm coming from. Chrome+NVDA also lets you navigate and activate inert checkboxes, but that's likely a Chrome implementation bug or NVDA bug.

I am probably putting the cart before the horse a bit with my explainer. The problem is I don't see any implementation of inert being reasonable from a performance viewpoint with all the tree-walking that is required for set Disabled State. Considering showModal() makes the entire #document inert, it's probably a guaranteed framedrop on most devices.

Nothing in inert spec says inert needs to be he hidden from accessibility. But if implementers can treat inert the same as they treat content-visibility, (and not have to treewalk), then implementation can be more reasonable. Also, I'm actively tracking Chrome, but Firefox and Safari suffer from the same long processing requirement of the entire DOM tree. Saying both content-visibility and inert apply a common set of characteristics on trees may help alleviate implementation pain. I'm not entirely sure why content-visibility doesn't need to treewalk, whereas inert does. From user interaction perspective, they should both be skipped equally (hence the shared logic proposition).

@Loirooriol
Copy link
Contributor

Inert can't be treated as content-visibility: hidden, because inert contents are still painted and their size is taken into account for intrinsic sizing. If you set :root {content-visivility: hidden}, then there is no tree walk because no content is laid out.

@clshortfuse
Copy link
Author

@Loirooriol Thanks. Maybe I'm not explaining it clearly. it's not a matter of making inert treated as content-visiblity:hidden. That makes no sense. It's the matter of making them the same base in terms abstraction:

If all content-visiblity:hidden are implicitly inert, then an element can apply the same logic whether it is visible or inert. In psuedocode:

  • ContentVisibilityHiddenElement implements InertElement.

Or a shared base type:

  • ContentVisibilityHiddenElement implements NonInteractiveElement
  • InertElement implements NonInteractiveElement

But the rules in spec for inert do not match the rules for content-visiblity:hidden. Inert disables elements internally and has optional find-in-page whereas content-visibilty:hidden removes from accessibility tree and excludes find-in-page results.

Diagrams:

image

image

@clshortfuse
Copy link
Author

I apologized. I misunderstood the Disabled State to the same as a form control disabled state, which it is not. It is an interactivity state. That means that there is no real required treewalking to change the style or layout (eg: :disabled) and implementers should probably address performance concerns based their own code structure.

That means this is would be strictly a language clarity change, not functionality change. Still, saying content-visiblity:hidden is inherently inert in spec could allow them to share logic without concerns of falling out of spec.

@fantasai fantasai added css-contain-1 privacy-needs-resolution Issue the Privacy Group has raised and looks for a response on. css-contain-2 Current Work labels Nov 16, 2022
@svgeesus svgeesus changed the title [css-contain][inert]: inert and hidden containments should share common logic [css-contain-2][inert]: inert and hidden containments should share common logic Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-contain-2 Current Work privacy-needs-resolution Issue the Privacy Group has raised and looks for a response on.
Projects
None yet
Development

No branches or pull requests

4 participants