HTML 验证:为什么将交互元素放入交互元素内无效?

gau*_*430 5 html accessibility semantic-markup wai-aria

免责声明:我知道它不是有效的 HTML。我想了解为什么不允许?

W3C 建议交互元素button不得a包含其他交互元素。

我可以找到很多提到此规则和一些解决方法的资源,还有一些与此规则如何影响可访问性和屏幕阅读器相关的资源,但几乎所有这些资源都讨论了这是一个要求这一事实,但没有解释原因。

https://adrianroselli.com/2016/12/be-wary-of-nesting-roles.html

https://codepen.io/vloux/pen/wXGyOv

在 <button> 内嵌套 <a> 在 Firefox 中不起作用

https://github.com/dequelabs/axe-core/issues/601

我真的无法找到为什么不允许这样做的解释?它会导致任何可用性问题吗?

这是一个相关的问题: 为什么不应在锚点内使用交互元素?

接受的答案是令人满意的,但不足以使该规则成为一项要求。使用正确的事件处理可以避免所描述的情况。

另外,如果嵌套的交互式内容无效,我们应该如何拥有这样的内容:

整体可点击的卡片,并且内部还有可点击的辅助 CTA。我知道解决方法是在卡内设置主要和次要 CTA,但上述内容是否也应该被允许?

这是一个小提琴: https: //jsfiddle.net/t9qbwas5/2/

<button type="button" class="card">
  The card itself is the primary CTA.
  <br/>
  <br/>
  some important content to read through.
  some important content to read through.
  some important content to read through.
  <div class="cta">
   Secondary CTA
  </div>
</button>

.cta {
  padding: 4px;
  background: #00a9a9;
  color: white;
  width: 80px;
  margin: auto;
  margin-top: 8px;
  margin-bottom: 8px;
}

.card {
  width: 200px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在上面的示例中,我通过在按钮内使用可点击的 div 来实现这一点,但这不是语义(?),也是功能方面的,它是另一个元素内的交互式元素。我试图了解,即使我使用此解决方法,嵌套交互元素是否从根本上是错误的?这是一个糟糕的设计/可用性实践吗?

Mhm*_*z_A 1

一个重要的问题与事件捕获有关;如果您单击嵌套在另一个交互式元素内的交互式元素(例如,可select点击的内部button),则会出现干扰,并且可能会发生两种情况,具体取决于浏览器;

\n\n
\n

情况 1 是两个元素都会引发该事件(例如click) event\n \xc2\xa0

\n\n

情况 2 是父元素将捕获事件,而嵌套元素不会引发该事件event

\n
\n\n

事实上,这两种情况都会导致非确定性行为;

\n\n

这实际上并不限于click事件,而是click事件更加有形;此外,屏幕阅读器将无法解析标记;键盘交互无法按预期工作;在下面的代码片段中尝试一下:

\n\n

\r\n
\r\n
del.addEventListener(\'click\', function(){\r\n  console.log(\'deleting ...\')\r\n})\r\n\r\nsave.addEventListener(\'click\', function(){\r\n  console.log(\'saving ...\')\r\n})\r\n\r\nsel.addEventListener(\'change\', function(){\r\n  console.log(\'changing to\', sel.value)\r\n})
Run Code Online (Sandbox Code Playgroud)\r\n
<div id=\'del\'>\r\ndelete \r\n<button id=\'save\'> save \r\n<select id=\'sel\'>\r\n  <option>foo</option>\r\n  <option>bar</option>\r\n<select>\r\n<input name=\'a\' type=\'radio\' />\r\n<input name=\'a\' type=\'radio\' />\r\n<input name=\'a\' type=\'radio\' />\r\n\r\n</button>\r\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n