假设我们有一个 <div>
。
我们仅希望此 div 在悬停时可见,因此
div:hover {
opacity: 1;
}
我们也需要焦点样式,以实现无障碍性,因此
div:hover,
div:focus {
opacity: 1;
}
但是 div 本身无法获得焦点,因此我们需要
<div tabindex="0">
</div>
此 div 中包含内容。不仅是文本,还有链接。
<div tabindex="0">
<p>This little piggy went to market.</p>
<a href="#market">Go to market</a>
</div>
这就是事情变得棘手的地方。
一旦焦点从 div 移动到其内部的锚链接,div 就不再处于焦点状态,这会导致这种奇怪且可能令人困惑的情况

这里的一种解决方案是确保当其内部的任何内容获得焦点时,div 保持可见。新的 CSS 在这里为我们提供了支持
div:hover,
div:focus,
div:focus-within {
opacity: 1;
}
GIF 工作
但 :focus-within
的浏览器支持不是很好。如果它完美无缺,这就是我们唯一需要的。事实上,我们甚至不需要 :focus
,因为 :focus-within
也处理了这一点。
但在那之前,我们可能需要 JavaScript 来帮忙。您实际处理此问题的方法取决于具体情况,但思路大概如下…
- 当某个元素获得焦点时…
- 如果该元素的父元素也可聚焦,请确保它可见
- 当链接失去焦点时…
- 您为确保父元素可见所做的一切都将被反转
这里有很多需要考虑的事情,比如您实际上想要监视哪些元素、如何使它们可见以及您希望向上遍历树多远。
类似这样的方法是一种非常基本的方法
var link = document.querySelector(".deal-with-focus-with-javascript");
link.addEventListener("focus", function() {
link.parentElement.classList.add("focus");
});
link.addEventListener("blur", function() {
link.parentElement.classList.remove("focus");
});
查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的 :focus-within 有用的 a11y 技巧。
实现此行为的另一种方法是使用(冒泡)focusin 和 focusout 事件。
我敢肯定,有一种很好的方法可以使
focusin
和/或focusout
事件在这里有所帮助,因为它们会冒泡(而focus
和blur
不会)。https://mdn.org.cn/en-US/docs/Web/Events/focusin
https://mdn.org.cn/en-US/docs/Web/Events/focusout
这将是下拉导航的一个很好的解决方案,该导航主要仅通过将鼠标悬停在父列表上才能显示。如果我们可以将焦点放在子菜单链接上并保持父元素可见等。
@Taufik Nurrohman
https://stackoverflow.com/a/10207668/778809
https://stackoverflow.com/a/10207832/778809