【问题标题】:Tab accessibility within a hover state悬停状态下的选项卡可访问性
【发布时间】:2018-11-07 13:28:51
【问题描述】:

我有一个组件,它在悬停时会显示一个按钮和一个可以单击的链接。这不是菜单...只是页面中间的一个框。

对于可访问性,我希望用户能够使用标签进入容器(现在发生,并在 .HiddenUntilHover 类中显示内容)并且还继续标签到悬停时显示的按钮和链接/聚焦状态。

现在您可以专注于容器并查看悬停状态;但是,当您使用选项卡时,它只会转到下一个元素,并且不允许您在悬停状态下使用选项卡到按钮或链接。

伪代码示例:

/* My component .jsx */
<div tabIndex="0" className="MainContainer">
 <div className="SomeOtherClass">
   <div className="HiddenUntilHover">
     /* I would like to be able to tab to these clickable things! */
     <button>Click me!</button>
     <a href="...">I am also clickable</a>
   </div>
 </div>
</div>

还有我的 SCSS:

.HiddenUntilHover {
  display: none;
}

MainContainer:focus,
MainContainer:hover,
> .HiddenUntilHover {
    display: block
}

【问题讨论】:

  • 我认为您在MainContainer 之前缺少一个点(。),我认为应该是这样的.MainContainer。对吗?

标签: css reactjs sass accessibility jsx


【解决方案1】:

几天前我遇到了这个问题,我使用 css 类解决了这个问题,使悬停的内容可以通过键盘导航访问。

我完成这项工作的方法是使用 css 伪类来确保当 div 元素处于活动状态并聚焦时,里面的按钮也会显示。具体来说,额外使用 :focus-within 和 :focus-visible 应该确保当您在列表项上按 Tab 时,它们的内容也会显示出来并且可以通过键盘访问。

.MainContainer  {
  &:not(:hover, :focus, :active, :focus-visible, :focus-within) {
    .HiddenUntilHover {
      visibility: hidden;
    }
  }
}
<body>
    <div tabIndex="0" className="MainContainer">
        Content
        <div className="SomeOtherClass">
          <div className="HiddenUntilHover">
            <button>Click me!</button>
            <a href="...">I am also clickable</a>
          </div>
        </div>
      </div>
  </body>

这是此工作的Codesandbox demo 的链接

【讨论】:

    【解决方案2】:

    悬停时出现的元素本质上是不可访问的。您的代码遇到了问题的一方面,难以通过键盘访问。 但是想想没有真正悬停概念的触摸屏:有什么方法可以触及智能手机或平板电脑上的按钮吗?

    要获得更务实的答案,如果您需要保持悬停状态,比已经发布的两个解决方案更简单的解决方案可能如下: 使用 focusin 和 focusout 事件。例如,请参阅 this question 以获得焦点/模糊的解释和差异,以及 this w3school doc 以获得浏览器兼容性。 您必须以不同的方式构建 HTML,例如:

    <div id="outer">
    <div id="hover">
    ...
    </div><!--hover-->
    <button>Your button which only appears on hover</utton>
    </div><!--outer-->
    

    以及使用一点js:

    $('#outer').on('focusin', __=>$('#hover').classNames.add('keep-visible'));
    $('#outer').on('focusout', __=>$('#hover').classNames.remove('keep-visible'));
    

    有一个相应的 .keep-visible 类,它将离开元素 display:block(我不是 CSS 专家,我让你写代码)。

    总体功能如下:当#outer 中的某个元素获得焦点时,由于冒泡而触发focusin 元素。在这种情况下,你把你的类 .keep-visible 让元素保持可见。 当焦点离开#outer 中的最后一个元素时,会触发focusout 事件。此时,您删除 .keep-visible 类,这会使元素消失。

    根据上面的链接,onfocusin/out 不是标准的,但包括 IE 在内的所有主要浏览器都支持。 Firefox 是最后一个在 52.0 中实现它的,所以它是一种事实上的标准;我们可以合理地预期它不会很快消失。

    【讨论】:

      【解决方案3】:

      当框处于焦点位置时,进一步点击按钮将使框模糊,这将隐藏它及其内容,因此焦点将移动到下一个可访问的元素。我认为这是您正在经历的行为。

      您可以考虑在框获得焦点时插入aria-activedescendant 或tabindex 属性。这需要一点 JavaScript。

      严格来说,您不需要依赖悬停状态来使该控件可访问。您可以拥有一个不是隐藏 (display:none) 框的 DOM 子项的屏幕外(或剪辑)按钮/链接。如果您采用这种方法,请阅读aria-owns 属性。

      只要它被标记为按钮或链接(或具有tabindex="0" 设置),并且没有“真正”隐藏,就应该可以使用标签。

      【讨论】:

      • 有什么例子吗?
      【解决方案4】:

      尝试增加类MainContainer的属性 例如。

      .MainContainer {
        width: 100%;
        height: 100px;
      }
      .MainContainer .HiddenUntilHover {
        display: none;
      }
      .MainContainer:hover .HiddenUntilHover, .MainContainer:focus .HiddenUntilHover {
        display: block;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-14
        相关资源
        最近更新 更多