Skip to content

Commit 066fa0a

Browse files
committed
Connect HTML spec up to new CSS interactivity property
I was a bit unsure about a few parts of this PR, so help would be appreciated from the editors. The idea is: 1. Remove duplication - allow the CSS spec to define the *concept* of "inert". 2. Make the `inert` HTML attribute set `interactivity:inert` via a new UA stylesheet rule. 3. Make modal dialogs non-inert via an `interactivity:auto` UA stylesheet rule. {eventual step 4} A rule likely needs to be added for fullscreen elements also, setting `interactivity:auto`. Fix reference Add a bunch of notes, and refactor some things Address comments Start on "marked as explicitly inert" Semi-revert the "marked as explicitly inert" approach, and tweak Resolve nits Add more to the Note about why the behavior is the way it is Address nit Merge fixup Final
1 parent d7053d8 commit 066fa0a

File tree

1 file changed

+84
-42
lines changed

1 file changed

+84
-42
lines changed

source

+84-42
Original file line numberDiff line numberDiff line change
@@ -4008,6 +4008,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
40084008
<dfn data-x-href="https://drafts.csswg.org/css-ui/#devolved">devolved widget</dfn> state.</li>
40094009
<li>The <dfn data-x-href="https://drafts.csswg.org/css-ui-4/#pointer-events-control">'pointer-events'</dfn> property</li>
40104010
<li>The <dfn data-x-href="https://drafts.csswg.org/css-ui-4/#content-selection">'user-select'</dfn> property</li>
4011+
<li>The <dfn data-x-href="https://drafts.csswg.org/css-ui-4/#inertness" data-x="css-interactivity">'interactivity'</dfn> property, and its
4012+
<dfn data-x-href="https://drafts.csswg.org/css-ui/#valdef-interactivity-auto" data-x="interactivity-auto">'auto'</dfn> and
4013+
<dfn data-x-href="https://drafts.csswg.org/css-ui/#valdef-interactivity-inert" data-x="interactivity-inert">'inert'</dfn> values.</li>
4014+
<li>The <dfn data-x-href="https://drafts.csswg.org/css-ui-4/#inert">inert</dfn> concept</li>
40114015
</ul>
40124016

40134017
<p>The algorithm to <dfn
@@ -62143,8 +62147,8 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
6214362147
request">close requests</span>, will no longer be able to close the dialog.</p></li>
6214462148

6214562149
<li><p>If the dialog was shown using its <code data-x="dom-dialog-showModal">showModal()</code>
62146-
method, the <code>Document</code> will still be <span data-x="blocked by a modal
62147-
dialog">blocked</span>.</p></li>
62150+
method, the <code>Document</code> will still be <span data-x="blocked by a
62151+
modal">blocked</span>.</p></li>
6214862152
</ul>
6214962153

6215062154
<p>For these reasons, it is generally better to never remove the <code
@@ -62462,12 +62466,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
6246262466
dialogs list</span> does not <span data-x="list contains">contain</span>
6246362467
<var>subject</var>.</p></li>
6246462468

62465-
<li><p>Add <var>subject</var> to <var>subject</var>'s <span>node document</span>'s <span>open
62466-
dialogs list</span>.</p></li>
62467-
6246862469
<li>
62469-
<p>Let <var>subject</var>'s <span>node document</span> be <span data-x="blocked by a modal
62470-
dialog">blocked by the modal dialog</span> <var>subject</var>.</p>
62470+
<p>Add <var>subject</var> to <var>subject</var>'s <span>node document</span>'s <span>open
62471+
dialogs list</span>.</p>
6247162472

6247262473
<p class="note" id="note-dialog-plus-focus-fixup">This will cause the <span>focused area of the
6247362474
document</span> to become <span>inert</span> (unless that currently focused area is a
@@ -79967,56 +79968,89 @@ interface <dfn interface>VisibilityStateEntry</dfn> : <span>PerformanceEntry</sp
7996779968
<p class="note">See also <code data-x="attr-inert">inert</code> for an explanation of the
7996879969
attribute of the same name.</p>
7996979970

79970-
<p>A node (in particular elements and text nodes) can be <dfn>inert</dfn>. When a node is
79971-
<span>inert</span>:</p>
79972-
79971+
<p>An element or <code>Text</code> <var>node</var> must be considered <span>inert</span> if one of
79972+
the following is true:</p>
7997379973
<ul>
79974-
<li><p>Hit-testing must act as if the <span>'pointer-events'</span> CSS property were set to
79975-
'none'.</p></li>
79976-
79977-
<li><p>Text selection functionality must act as if the <span>'user-select'</span> CSS property
79978-
were set to 'none'.</p></li>
79979-
79980-
<li><p>If it is <span>editable</span>, the node behaves as if it were non-editable.</p></li>
79981-
79982-
<li><p>The user agent should ignore the node for the purposes of <span>find-in-page</span>.</p></li>
79974+
<li><p><var>node</var> is <span>inert via modal blockage</span>.</p></li>
79975+
<li><p><var>node</var>'s <span data-x="css-interactivity">'interactivity'</span> property has a
79976+
<span>computed value</span> of <span data-x="interactivity-inert">'inert'</span>.</p></li>
7998379977
</ul>
7998479978

79985-
<p class="note">Inert nodes generally cannot be focused, and user agents do not expose the inert
79986-
nodes to accessibility APIs or assistive technologies. Inert nodes that are <span
79979+
<p class="note">The behavior of inert nodes is defined by the CSS concept of <span>inert</span>.
79980+
Inert nodes generally cannot be focused, and user agents do not expose the inert nodes to
79981+
accessibility APIs or assistive technologies. Inert nodes that are <span
7998779982
data-x="concept-command">commands</span> will become inoperable to users, in the manner described
7998879983
above.</p>
7998979984

79990-
<p>User agents may allow the user to override the restrictions on <span>find-in-page</span> and
79991-
text selection, however.</p>
79992-
79993-
<p>By default, a node is not <span>inert</span>.</p>
79994-
7999579985
<h4>Modal dialogs and inert subtrees</h4>
7999679986

79997-
<p>A <code>Document</code> <var>document</var> is <dfn>blocked by a modal dialog</dfn>
79998-
<var>subject</var> if <var>subject</var> is the topmost <code>dialog</code> element in
79999-
<var>document</var>'s <span>top layer</span>. While <var>document</var> is so blocked, every node
80000-
that is <span>connected</span> to <var>document</var>, with the exception of the
80001-
<var>subject</var> element and its <span>flat tree</span> descendants, must become
80002-
<span>inert</span>.</p>
79987+
<p>A <code>Document</code> <var>document</var> is <dfn>blocked by a modal</dfn> <var>subject</var>
79988+
if <var>subject</var> is the topmost <code>dialog</code> element in <var>document</var>'s
79989+
<span>top layer</span>. While <var>document</var> is so blocked, every element or
79990+
<code>Text</code> node that is <span>connected</span> to <var>document</var>, with the exception
79991+
of the <var>subject</var> element and its <span>flat tree</span> descendants, is considered
79992+
<dfn>inert via modal blockage</dfn>.</p>
8000379993

80004-
<p><var>subject</var> can additionally become <span>inert</span> via the <code
80005-
data-x="attr-inert">inert</code> attribute, but only if specified on <var>subject</var> itself
80006-
(i.e., <var>subject</var> escapes inertness of ancestors); <var>subject</var>'s <span>flat
80007-
tree</span> descendants can become <span>inert</span> in a similar fashion.</p>
79994+
<p class="note">In this case, <var>subject</var> can additionally become <span>inert</span>
79995+
via the <code data-x="attr-inert">inert</code> attribute, but only if specified on
79996+
<var>subject</var> itself (i.e., <var>subject</var> escapes inertness of ancestors);
79997+
<var>subject</var>'s <span>flat tree</span> descendants can become <span>inert</span> in a similar
79998+
fashion.</p>
8000879999

8000980000
<p class="note">The <code>dialog</code> element's <code
8001080001
data-x="dom-dialog-showModal">showModal()</code> method causes this mechanism to trigger, by <span
8001180002
data-x="add an element to the top layer">adding</span> the <code>dialog</code> element to its
8001280003
<span>node document</span>'s <span>top layer</span>.</p>
8001380004

80005+
<div class="note">
80006+
<p>The HTML Standard defines several ways for an element to be <span>inert</span>,
80007+
including the <code data-x="attr-inert">inert</code> attribute, and the <span>blocked by a
80008+
modal</span> concept. The <ref>CSSUI</ref> specification additionally provides the <span
80009+
data-x="css-interactivity">'interactivity'</span> property. These methods don't directly affect
80010+
each other, but do interact. The relevant UA stylesheets that define this
80011+
behavior are included in the HTML Standard.</p>
80012+
80013+
<p>The effect of the <code class="css" data-x="">:modal { interactivity: auto; }</code> UA
80014+
stylesheet rule is to escape interactivity property inertness from ancestor elements of the modal
80015+
dialog. For instance, if the two dialogs below are modal, they will not be inert when rendered in
80016+
the top layer:</p>
80017+
80018+
<pre><code class="html">&lt;div inert>
80019+
&lt;dialog>&lt;/dialog>
80020+
&lt;/div>
80021+
&lt;div style="interactivity:inert">
80022+
&lt;dialog>&lt;/dialog>
80023+
&lt;/div></code></pre>
80024+
80025+
<p>The reason that HTML "overrides" the <span data-x="css-interactivity">'interactivity'</span>
80026+
property in the case of modal dialogs is that accessibility technology requires modal dialogs to
80027+
be truly modal. Content outside of an open modal dialog needs to always be inert. For this
80028+
reason, the spec is designed in such a way that developers are unable to override modal dialog
80029+
<span data-x="css-interactivity">'interactivity'</span>, while still being able to override
80030+
other developer-controlled forms of interactivity such as the <code
80031+
data-x="attr-inert">inert</code> attribute.</p>
80032+
</div>
80033+
8001480034
<h4>The <dfn data-x="attr-inert"><code>inert</code></dfn> attribute</h4>
8001580035

80016-
<p>The <code data-x="attr-inert">inert</code> attribute is a <span>boolean attribute</span> that
80017-
indicates, by its presence, that the element and all its <span>flat tree</span> descendants which
80018-
don't otherwise escape inertness (such as modal dialogs) are to be made <span>inert</span> by the
80019-
user agent.</p>
80036+
<p>All <span>HTML elements</span> may have the <code data-x="attr-inert">inert</code>
80037+
attribute, a <span>boolean attribute</span>.</p>
80038+
80039+
<p>When an element has the <span>inert</span> attribute, it indicates that the element and its
80040+
<span data-x="descendant">descendants</span> should become <span>inert</span>. This requirement
80041+
may be implemented indirectly through the style layer. For example, a web browser could implement
80042+
these requirements <a href="#hiddenCSS">using the rules suggested in the Rendering
80043+
section</a>.</p>
80044+
80045+
<div class="note">
80046+
<p>Because this attribute is typically implemented using CSS, it's also possible to override it
80047+
using CSS. For example:</p>
80048+
80049+
<pre><code class="html">&lt;div inert style="interactivity: auto">&lt;/div></code></pre>
80050+
80051+
<p>In this case, the <code class="html" data-x="">&lt;div></code> will not be <span>inert</span>
80052+
because the author styles have overridden the user agent styles.</p>
80053+
</div>
8002080054

8002180055
<p>An inert subtree should not contain any content or controls which are critical to
8002280056
understanding or using aspects of the page which are not in the inert state. Content in an inert
@@ -81757,8 +81791,8 @@ dictionary <dfn dictionary>CommandEventInit</dfn> : <span>EventInit</span> {
8175781791
<var>starting point</var> being the <span>top-level traversable</span> itself.</p>
8175881792

8175981793
<!-- in theory, the top-level traversable _always_ has at least one focusable area: the
81760-
viewport. Even a "blocked by a modal dialog" doesn't disable the viewport (since the Document is
81761-
its DOM anchor, and the Document isn't made inert by "blocked by a modal dialog"). Note that
81794+
viewport. Even a "blocked by a modal" doesn't disable the viewport (since the Document is
81795+
its DOM anchor, and the Document isn't made inert by "blocked by a modal"). Note that
8176281796
child navigables can have inert viewports, though (if the navigable container
8176381797
itself is inert, for example) -->
8176481798
</li>
@@ -136486,6 +136520,14 @@ dialog:popover-open {
136486136520
display:block;
136487136521
}
136488136522

136523+
:modal {
136524+
interactivity: auto;
136525+
}
136526+
136527+
[inert] {
136528+
interactivity: inert;
136529+
}
136530+
136489136531
[popover] {
136490136532
position: fixed;
136491136533
inset: 0;

0 commit comments

Comments
 (0)