对话框中显示 z-index 的输入的可访问性
Accessibility of inputs with z-index showing in dialog
我有一个要求,显示一个对话框,它集成了来自后台的一些输入(不是全部),因为它增强了它们的功能。所以我希望它们融入对话框并可以从那里进行编辑。这对 z-index 来说不是很难,但输入必须在对话框标记之外。我想知道这是否适用于屏幕 reader(我的猜测是它不适用),如果不适用:你有什么建议我可以如何在不调整整个表单的每个输入的情况下完成这项工作?
Here 是我希望以易于访问的方式完成的示例:
function showDialog()
{
document.getElementById("dialog").style.display = 'table';
}
function hideDialog()
{
document.getElementById("dialog").style.display = 'none';
}
form > div
{
margin: 10px;
}
.layer
{
margin: 0;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
}
.showThrough
{
position: relative;
z-index: 1100;
}
<form>
<div class="showThrough">
<label>Input 1:</label><input/>
</div>
<div>
<label>Input 2:</label><input/>
</div>
<div class="showThrough">
<label>Input 3:</label><input class="showThrough"/>
</div>
<input type="button" onclick="showDialog()" value="Show dialog"/>
<input type="button" value="Submit"/>
<div id="dialog" role="dialog" class="layer" style="display: none;">
<input type="button" value="Close" onclick="hideDialog()"
style="position: absolute; bottom: 15px; right: 15px;"/>
</div>
</form>
你需要思考的问题
我在大多数模态框上看到的最大问题是它们允许焦点在它们之外。
您不能只阻止用户使用 Tab 键,因为这不是大多数屏幕 reader 用户浏览页面的方式(他们使用标题 (h1-h6)、超链接、表单输入等的快捷方式。 ).
因此,您必须将 aria-hidden="true"
和 tabindex="-1"
添加到页面上不属于模态的每个元素,然后在模态消失时再次将其删除(这可以应用于容器,因为它们的所有 children 都将无法获得焦点,因此它并不像听起来那么可怕。
您还需要在不属于 'modal' 的所有 'disabled' 字段上使用此方法(我将它们放在引号中,因为它们没有被禁用,而且这实际上不是模态!)。
您还需要确保可以使用 Esc 键关闭模态,因为这是预期的行为。
您还需要确保第一个 <input>
在您启动模式时以编程方式获得焦点,否则当您禁用 'submit' 按钮时,焦点可能不会到达您想要的位置。
为什么要这样做,有没有更好的方法?
您没有说明为什么存在此要求,但如果它只是为了突出显示基本字段,您最好在它们上使用一个大而粗的轮廓,用您的按钮激活并且不干扰流程文档。
有时要求似乎是个好主意,但在您展示的示例中(我知道它被剥离了)我发现 'close' 按钮不在文档的位置并且它添加了一个烦人的东西完成后必须关闭对话框的额外步骤(您是否应该不允许从对话框中提交?)。
如果这是一个必需的功能,而你不能说服权力机构说这不是一个好主意(我知道它是什么样的!),你最好创建一个实际的模态然后填充主表单中的字段 JavaScript 模式关闭/输入更新,因为这将减少您需要在页面上禁用的内容。
即您只需将必填字段克隆到您的模式中,然后在整个文档的 <header>
和 <main>
上使用 tabindex="-1"
和 aria-hidden="true"
来管理焦点。
这使得页面在未来更易于维护,因为您不必在每次向页面添加部分时都更新脚本。
如果您的表单是动态的(字段会更改),那么您可以只使用 JavaScript 在模式中创建表单(即循环遍历表单字段,找到 'showThrough' 项并克隆它们进入模式。)或在后端进行。
我有一个要求,显示一个对话框,它集成了来自后台的一些输入(不是全部),因为它增强了它们的功能。所以我希望它们融入对话框并可以从那里进行编辑。这对 z-index 来说不是很难,但输入必须在对话框标记之外。我想知道这是否适用于屏幕 reader(我的猜测是它不适用),如果不适用:你有什么建议我可以如何在不调整整个表单的每个输入的情况下完成这项工作?
Here 是我希望以易于访问的方式完成的示例:
function showDialog()
{
document.getElementById("dialog").style.display = 'table';
}
function hideDialog()
{
document.getElementById("dialog").style.display = 'none';
}
form > div
{
margin: 10px;
}
.layer
{
margin: 0;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
}
.showThrough
{
position: relative;
z-index: 1100;
}
<form>
<div class="showThrough">
<label>Input 1:</label><input/>
</div>
<div>
<label>Input 2:</label><input/>
</div>
<div class="showThrough">
<label>Input 3:</label><input class="showThrough"/>
</div>
<input type="button" onclick="showDialog()" value="Show dialog"/>
<input type="button" value="Submit"/>
<div id="dialog" role="dialog" class="layer" style="display: none;">
<input type="button" value="Close" onclick="hideDialog()"
style="position: absolute; bottom: 15px; right: 15px;"/>
</div>
</form>
你需要思考的问题
我在大多数模态框上看到的最大问题是它们允许焦点在它们之外。
您不能只阻止用户使用 Tab 键,因为这不是大多数屏幕 reader 用户浏览页面的方式(他们使用标题 (h1-h6)、超链接、表单输入等的快捷方式。 ).
因此,您必须将 aria-hidden="true"
和 tabindex="-1"
添加到页面上不属于模态的每个元素,然后在模态消失时再次将其删除(这可以应用于容器,因为它们的所有 children 都将无法获得焦点,因此它并不像听起来那么可怕。
您还需要在不属于 'modal' 的所有 'disabled' 字段上使用此方法(我将它们放在引号中,因为它们没有被禁用,而且这实际上不是模态!)。
您还需要确保可以使用 Esc 键关闭模态,因为这是预期的行为。
您还需要确保第一个 <input>
在您启动模式时以编程方式获得焦点,否则当您禁用 'submit' 按钮时,焦点可能不会到达您想要的位置。
为什么要这样做,有没有更好的方法?
您没有说明为什么存在此要求,但如果它只是为了突出显示基本字段,您最好在它们上使用一个大而粗的轮廓,用您的按钮激活并且不干扰流程文档。
有时要求似乎是个好主意,但在您展示的示例中(我知道它被剥离了)我发现 'close' 按钮不在文档的位置并且它添加了一个烦人的东西完成后必须关闭对话框的额外步骤(您是否应该不允许从对话框中提交?)。
如果这是一个必需的功能,而你不能说服权力机构说这不是一个好主意(我知道它是什么样的!),你最好创建一个实际的模态然后填充主表单中的字段 JavaScript 模式关闭/输入更新,因为这将减少您需要在页面上禁用的内容。
即您只需将必填字段克隆到您的模式中,然后在整个文档的 <header>
和 <main>
上使用 tabindex="-1"
和 aria-hidden="true"
来管理焦点。
这使得页面在未来更易于维护,因为您不必在每次向页面添加部分时都更新脚本。
如果您的表单是动态的(字段会更改),那么您可以只使用 JavaScript 在模式中创建表单(即循环遍历表单字段,找到 'showThrough' 项并克隆它们进入模式。)或在后端进行。