【问题标题】:tabindex -1 not working for child elementstabindex -1 不适用于子元素
【发布时间】:2017-03-13 11:01:19
【问题描述】:

我有一个 div 标签,其中加载了一些内容。里面的内容可以有可聚焦的按钮、锚元素等。我无法控制内容,但我可以修改“div”标签属性。

我的问题是即使我将 tabIndex -1 指定给 div 标签,焦点仍会转到内容(锚点、按钮等)。

<!-- HTML content here -->
<div tabindex="-1" id="externalContent">
  <div>
    ...
    <button>click me</button> <!-- Focus shouldn't come here -->
  </div>
</div>
<!-- HTML content here -->

有没有办法在切换时跳过整个内容?它肯定不适用于上面的代码。

【问题讨论】:

  • 您可以使用 tabindex="-1".... 请注意,这是 HTML5 功能,可能不适用于旧浏览器。 stackoverflow.com/questions/5192859/…
  • 也许您可以使用 jquery 将 tabindex="-1" 获取到 div 内所有可能的元素...
  • 为什么要阻止焦点转到内容?如果内容实际上是交互式的——即如果你可以用鼠标点击按钮/链接——你通常也应该让它们获得键盘焦点。
  • 此处“externalContent”中的内容在页面加载时部分可见,因此对于 a11y,我需要从标签顺序中跳过它。我不想为每个孩子附加 tabindex=-1,因为一旦内容完全可见,我需要反转它。
  • 一个常见的用例:在网页上显示一个对话框。

标签: html accessibility tabindex


【解决方案1】:

不知道为什么还没有人提到visibility: hidden。在处理非视觉元素的尺寸时,设置display: none 在某些情况下会搞乱逻辑。 visibility 将像 opacity: 0 一样保留维度,但也会禁用任何可选项卡的子项。

例子:

<div style="visibility: hidden;">
    <a href="#">I'm only tabbable if my parent is visible!</a>
</div>

【讨论】:

  • 这是最好的解决方案。在父级上设置 tabindex="-1" 不会从子级中删除 tabindex,但在父级上设置可见性:隐藏会从子级中删除 tabindex。
  • 谢谢!这个很棒的解决方案为我节省了很多工作。在我看来,这应该是公认的答案。
  • 一个陷阱——有了可见性,孩子可以在自己身上设置visibility:visible,这将允许它在visibility: hidden祖先中接收键盘焦点:jakearchibald.com/2014/visible-undoes-hidden
【解决方案2】:

设置tabindex="-1" 允许您使用脚本设置元素的焦点,但 将其置于页面的Tab 顺序中。它也不会拉出键盘标签顺序的子元素退出

tabindex="-1" 在您需要将焦点转移到通过脚本或用户操作之外的内容更新时非常方便。

如果您尝试从 tabindex 中完全删除一个元素,无论是对于屏幕阅读器还是键盘用户,您都可能必须在以下选项之一中进行选择:

  1. 完全隐藏(通过display: none),
  2. 在元素上使用脚本,这样当它获得焦点时,脚本会将焦点转移到其他地方。

没有上下文(一个有效的 URL,一个你想要这样做的原因),这听起来很像可访问性的相反。我鼓励你不要乱用焦点,除非你有很好的理由。

【讨论】:

  • "设置 tabindex="-1"...不会从键盘标签顺序中提取某些内容。"在什么浏览器上?将 tabindex 设置为 -1 对我来说总是可以按 Tab 键顺序跳过一个对象。
  • 抱歉,意思是说它不会将项目的 children 拉出标签顺序。相应地编辑了答案。在 OP 的问题中,它不会将嵌套的 &lt;button&gt; 拉出标签顺序,而只是容器(它本身不会获得焦点,因为它是 &lt;div&gt;)。
  • 是的,使用“脚本”也是我能找到的唯一选择。无法显示任何内容,因为我的“externalContent”div 中的内容在页面加载时部分可见。
  • 希望能够在没有外部事件监听器的情况下实现这一点!
【解决方案3】:

可以将元素 BOTH 可见不可聚焦 与其子元素一起保留。

这是通过 HTML 属性 inert: https://html.spec.whatwg.org/multipage/interaction.html#inert 完成的。

它尚未得到广泛支持,但有一个 polyfill:https://github.com/WICG/inert

npm install --save wicg-inert

require('wicg-inert')

<section inert>
  I am visible, but not focusable! 
</section>

【讨论】:

  • fwiw 我想你会这样做:&lt;section inert /&gt;
  • @TheDembinski,嗯,我可能一直使用 react 语法。
  • &lt;section inert={true}&gt; -> &lt;section inert&gt;
【解决方案4】:

您可以使用的最接近的方法是使用 iframe 元素,使用 javascript 将您的 HTML 注入其中。

<a href="somewhere.html">first link</a>
<iframe id="iframeid" tabindex="-1"></iframe>
<a href="somewhere_else.html">second link</a>

<script>
    document.getElementById('iframeid').contentWindow.document.body.innerHTML="<button>click me</button>";
</script>

但是,这会导致可访问性问题,例如宣布您的键盘无法访问的链接或按钮。

【讨论】:

  • 由于可访问性问题,这对我来说不可行。
  • @AdarshKonchady 那么你的问题没有答案。如果您特别提出会导致可访问性问题的问题,您将无法访问。
  • @AdarshKonchady 您还应该谨慎阅读 Aardrian 警告:“这听起来很像可访问性的反面。”
【解决方案5】:
[tab-index="-1"] > * {
    visibility: hidden;
}

这会隐藏任何交互式子项以防止选项卡导航或鼠标单击,但会将父项留在影子 DOM 中,并保留所有大小的父项和子项。

【讨论】:

  • 不涉及影子 DOM。此处不能选择隐藏可见性,因为内容仍需要部分可见。
【解决方案6】:

为了让子元素的 tabindex -1,假设你有一个包装 div, // 关于反应的回答,当我们不希望网格过滤器折叠时可访问 //这个答案是针对一种特殊情况——我们没有 refs 和 tabIndex 道具对于大的嵌套元素确实很重要 // 渲染方法

// 如果 Input 和 Button 来自某种类型(例如 Material UI)的库,这些库没有将 tabIndex 作为道具并且不提供参考。

   render() {
    return (
    <div id="wrapper" tabIndex={isCollapsed ? -1 : 0 } >
      <div>
        <Input />
      </div>
      <div>
        <Button />
      </div>
    </div>
  )
}
componentDidMount() {
  this.changeTabIndex()
}

componentDidUpdate(prevProps, prevState){
  if(prevState.isCollapsed !== this.state.isCollapsed) {
     this.changeTabIndex();
  }
}

changeTabIndex() {
   const wrapper = document.getElementById("wrapper");
     const buttons = wrapper.getElementsByTagName("button");
     const inputs = wrapper.getElementsByTagName("input");
     const arr = Array.from(buttons).concat(Array.from(inputs));
     arr.foreach((elem) => { elem.setAttribute("tabIndex", this.state.isCollapsed ? -1 : 0 )});
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多