-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Implement dialog initial focus proposal #8199
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
Changes from all commits
2394e21
fd9c31d
b52e9b6
8da9666
2070d76
50c821f
844c49f
c15e1fc
4727fc0
8ff0298
da545c2
7003f1f
1ca7cbb
7dae27e
5907549
b09e68c
136592c
1f0a278
c6de43e
e4046aa
f60b5e2
3f56f1f
000aea4
30683ac
c95c97b
133d817
76ed03e
572a1c8
7585ed6
9fe975a
ca5d8e9
1763b9c
ee1a835
b9c63ca
494d638
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59129,8 +59129,88 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
<dd w-dev>Uses <code>HTMLDialogElement</code>.</dd> | ||
</dl> | ||
|
||
<p>The <code>dialog</code> element represents a part of an application that a user interacts with | ||
to perform a task, for example a dialog box, inspector, or window.</p> | ||
<p>The <code>dialog</code> element represents a transitory part of an application, in the form of | ||
a small window ("dialog box"), which the user interacts with to perform a task or gather | ||
information. Once the user is done, the dialog can be automatically closed by the application, or | ||
manually closed by the user.</p> | ||
|
||
<p>Especially for modal dialogs, which are a familiar pattern across all types of applications, | ||
authors should work to ensure that dialogs in their web applications behave in a way that is | ||
familiar to users of non-web applications.</p> | ||
|
||
<p class="note">As with all HTML elements, it is not conforming to use the <code>dialog</code> | ||
element when attempting to represent another type of control. For example, context menus, | ||
tooltips, and popup listboxes are not dialog boxes, so abusing the <code>dialog</code> element to | ||
implement these patterns is incorrect.</p> | ||
|
||
<p>An important part of user-facing dialog behavior is the placement of initial focus. The | ||
<span>dialog focusing steps</span> attempt to pick a good candidate for initial focus when a | ||
dialog is shown, but might not be a substitute for authors carefully thinking through the correct | ||
choice to match user expectations for a specific dialog. As such, authors should use the <code | ||
data-x="attr-fe-autofocus">autofocus</code> attribute on the descendant element of the dialog that | ||
the user is expected to immediately interact with after the dialog opens. If there is no such | ||
element, then authors should use the <code data-x="attr-fe-autofocus">autofocus</code> attribute | ||
on the <code>dialog</code> element itself.</p> | ||
|
||
<div class="example"> | ||
<p>In the following example, a dialog is used for editing the details of a product in an | ||
inventory management web application.</p> | ||
|
||
<pre><code class="html"><dialog> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sorry, this is totally on me, but I forgot why we changed this from the example at https://github.com/whatwg/html/wiki/dialog--initial-focus,-a-proposal#example . @scottaohara I vaguely remember you being involved? I'm not very happy with this example because it's just hard to believe the web developer would put the button before the input. The example at https://github.com/whatwg/html/wiki/dialog--initial-focus,-a-proposal#example is more believable. If there's something wrong with my initial version (I vaguely recall there was), could we try to come up with a more believable example here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I found the conversation. It's at #8199 (comment) (collapsed by default). I guess @annevk didn't like the example because it relied on the focusablity of readonly controls? I don't think that's so strange. The point of readonly (as opposed to disabled) is explicitly to be focusable/selectable. E.g. it's what I use in the second textbox in https://domenic.github.io/rewrapper/ . @annevk , are you OK reverting this to the previous example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed @domenic, far prefer the original example as this new one doesn't make sense. the original example is something i can point to many instances of in microsoft products. i'm confused by the original comment, indicating that Firefox did not autofocus readonly controls. testing today, focus goes to the readonly text field just fine (chrome and firefox), as i'd expect. So maybe Firefox has reversed course to match up with other implementations since october? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I tentatively reverted back to the previous example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, fair enough. |
||
<label>Product Number <input type="text" readonly></label> | ||
<label>Product Name <input type="text" autofocus></label> | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</dialog></code></pre> | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<p>If the <code data-x="attr-fe-autofocus">autofocus</code> attribute was not present, the | ||
Product Number field would have been focused by the dialog focusing steps. Although that is | ||
reasonable behavior, the author determined that the more relevant field to focus was the Product | ||
Name field, as the Product Number field is readonly and expects no user input. So, the author | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
used autofocus to override the default.</p> | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<p>Even if the author wants to focus the Product Number field by default, they are best off | ||
explicitly specifying that by using autofocus on that <code>input</code> element. This makes the | ||
intent obvious to future readers of the code, and ensures the code stays robust in the face of | ||
future updates. (For example, if another developer added a close button, and positioned it in the | ||
node tree before the Product Number field).</p> | ||
</div> | ||
|
||
<p>Another important aspect of user behavior is whether dialogs are scrollable or not. In some | ||
cases, overflow (and thus scrollability) cannot be avoided, e.g., when it is caused by the user's | ||
high text zoom settings. But in general, scrollable dialogs are not expected by users. Adding | ||
large text nodes directly to dialog elements is particularly bad as this is likely to cause the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this intended to be non-normative? If so, don't use "should". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I intended this to be normative when I wrote it. Do you think it's a bad normative requirement, e.g. because it's too vague? I'm not sure on the precedent there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the delay. Yes, I think it's not a good requirement because it's vague and not testable. Further, the wording "authors should work to ensure" makes the requirement about the work the author does, which is a bit off. If it's not testable, I think making it non-normative is better. e.g. s/should work/are encouraged/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see any remaining normative text in the section we're talking about, so I think this is resolved? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This paragraph is still there and still says "authors should work to ensure". |
||
dialog element itself to overflow. Authors are best off avoiding them.</p> | ||
|
||
<div class="example"> | ||
<p>The following terms of service dialog respects the above suggestions.</p> | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<pre><code class="html"><dialog style="height: 80vh;"> | ||
<div style="overflow: auto; height: 60vh;" autofocus> | ||
<p>By placing an order via this Web site on the first day of the fourth month of the year | ||
2010 Anno Domini, you agree to grant Us a non-transferable option to claim, for now and for | ||
ever more, your immortal soul.</p> | ||
<p>Should We wish to exercise this option, you agree to surrender your immortal soul, | ||
and any claim you may have on it, within 5 (five) working days of receiving written | ||
notification from this site or one of its duly authorized minions.</p> | ||
<!-- ... etc., with many more <p> elements ... --> | ||
</div> | ||
<form method="dialog"> | ||
<button type="submit" value="agree">Agree</button> | ||
<button type="submit" value="disagree">Disagree</button> | ||
</form> | ||
</dialog></code></pre> | ||
|
||
<p>Note how the <span>dialog focusing steps</span> would have picked the scrollable | ||
<code>div</code> element by default, but similarly to the previous example, we have placed <code | ||
data-x="attr-fe-autofocus">autofocus</code> on the <code>div</code> so as to be more explicit and | ||
robust against future changes.</p> | ||
|
||
<p>In contrast, if the <code>p</code> elements expressing the terms of service did not have such | ||
a wrapper <code>div</code> element, then the <code>dialog</code> itself would become scrollable, | ||
violating the above advice. Furthermore, in the absence of any <code | ||
data-x="attr-fe-autofocus">autofocus</code> attribute, such a markup pattern would have violated | ||
the above advice and tripped up the <span>dialog focusing steps</span>'s default behavior, and | ||
caused focus to jump to the Agree <code>button</code>, which is a bad user experience.</p> | ||
</div> | ||
|
||
<p>The <dfn element-attr for="dialog"><code data-x="attr-dialog-open">open</code></dfn> attribute | ||
is a <span>boolean attribute</span>. When specified, it indicates that the <code>dialog</code> | ||
|
@@ -59218,7 +59298,8 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
<li><p>Set the <code>dialog</code> element's <span>previously focused element</span> to the | ||
<span>focused</span> element.</p></li> | ||
|
||
<li><p>Run the <span>dialog focusing steps</span> for the <code>dialog</code> element.</p></li> | ||
<li><p>Run the <span>dialog focusing steps</span> given the <code>dialog</code> element and | ||
false.</p></li> | ||
</ol> | ||
|
||
<p>When the <dfn method for="HTMLDialogElement"><code | ||
|
@@ -59260,22 +59341,32 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
<li><p>Set the <var>subject</var>'s <span>previously focused element</span> to the | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span>focused</span> element.</p></li> | ||
|
||
<li><p>Run the <span>dialog focusing steps</span> for <var>subject</var>.</p></li> | ||
<li><p>Run the <span>dialog focusing steps</span> given <var>subject</var> and true.</p></li> | ||
</ol> | ||
|
||
<p>The <dfn>dialog focusing steps</dfn> for a <code>dialog</code> element <var>subject</var> are as follows:</p> | ||
<p>The <dfn>dialog focusing steps</dfn>, given a <code>dialog</code> element <var>subject</var> | ||
and a boolean <var>isModal</var>, are as follows:</p> | ||
|
||
<ol> | ||
<li><p>Let <var>control</var> be the <span>focus delegate</span> of <var>subject</var>.</p></li> | ||
<li><p>Let <var>control</var> be null.</p></li> | ||
|
||
<li><p>If <var>isModal</var> is true and <var>subject</var> has the <code | ||
data-x="attr-fe-autofocus">autofocus</code> attribute, then set <var>control</var> to | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<var>subject</var>.</p></li> | ||
josepharhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<li><p>If <var>control</var> is null, then set <var>control</var> to the <span>focus | ||
delegate</span> of <var>subject</var>.</p></li> | ||
|
||
<li><p>If <var>control</var> is null, then set <var>control</var> to <var>subject</var>.</p></li> | ||
|
||
<li> | ||
<p>Run the <span>focusing steps</span> for <var>control</var>.</p> | ||
|
||
<p class="note">If <var>control</var> is not <span>focusable</span>, this will do nothing. For | ||
modal dialogs, this means that any <a href="#note-dialog-plus-focus-fixup">earlier | ||
modifications</a> to the <span>focused area of the document</span> will apply.</p> | ||
<p class="note">If <var>control</var> is not <span>focusable</span>, this will do nothing. This | ||
would only happen if subject had no focus delegate, and the user agent decided that | ||
<code>dialog</code> elements were not generally focusable. In that case, any <a | ||
href="#note-dialog-plus-focus-fixup">earlier modifications</a> to the <span>focused area of the | ||
document</span> will apply.</p> | ||
</li> | ||
|
||
<li><p>Let <var>topDocument</var> be <var>control</var>'s <span>node navigable</span>'s <span | ||
|
@@ -76187,9 +76278,9 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> { | |
The element itself. | ||
<tr> | ||
<td headers="td-fa-1 th-fa-examples" colspan=2> | ||
<p class="example"><code>iframe</code>, <code data-x="attr-input-type-text"><input | ||
type=text></code>, sometimes <code data-x="a"><a href=""></code> (depending on platform | ||
conventions). | ||
<p class="example"><code>iframe</code>, <code>dialog</code>, <code | ||
data-x="attr-input-type-text"><input type=text></code>, sometimes <code data-x="a"><a | ||
href=""></code> (depending on platform conventions). | ||
|
||
<tbody> | ||
<tr> | ||
|
@@ -76805,11 +76896,18 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> { | |
order</span>:</p> | ||
|
||
<ol> | ||
<li><p>If <var>descendant</var> is a <span>focusable area</span>, then return | ||
<li><p>Let <var>focusableArea</var> be null.</p></li> | ||
|
||
<li><p>If <var>focusTarget</var> is a <code>dialog</code> element and <var>descendant</var> is | ||
<span>sequentially focusable</span>, then set <var>focusableArea</var> to | ||
<var>descendant</var>.</p></li> | ||
|
||
<li><p>Otherwise, if <var>focusTarget</var> is not a <code>dialog</code> and | ||
<var>descendant</var> is a <span>focusable area</span>, set <var>focusableArea</var> to | ||
<var>descendant</var>.</p></li> | ||
|
||
<li> | ||
<p>Let <var>focusableArea</var> be the result of <span data-x="get the focusable | ||
<p>Otherwise, set <var>focusableArea</var> to the result of <span data-x="get the focusable | ||
area">getting the focusable area</span> for <var>descendant</var> given | ||
<var>focusTrigger</var>.</p> | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.