Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML Validation: Why is it not valid to put an interactive element inside an interactive element?

Disclaimer: I understand that it is not valid HTML. I am trying to understand why is it not allowed?

W3C suggests that an interactive element like button or a mustn't contain another interactive element.

I could find a lot of resources mentioning this rule and some workarounds, also some resources related to how this impacts accessibility and screenreaders, but almost all of those resources talk about the fact that this is a requirement but do not explain why.

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

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

Nesting <a> inside <button> doesn't work in Firefox

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

I wasn't really able to find an explanation for why is it not allowed? does it lead to any usability problems?

This is a related question: Why should interactive element not be used within an anchor?

The accepted answer is satisfactory but is not enough to make this rule a requirement. The described situation can be avoided using proper event handling.

Also, if nested interactive content is invalid, how are we supposed to have something like this:

A card which is clickable as a whole, and also has a clickable secondary CTA inside it. I know a workaround would be to have a primary and secondary CTA inside the card, but shouldn't the above be allowed as well?

Here is a fiddle: 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;
}

enter image description here In the above example, I am achieving this by using a clickable div inside the button, but that is not semantic (?) and also functionality wise, it is an interactive element inside another one. I am trying to understand that even if I use this workaround, is it fundamentally wrong to have nested interactive elements? is it a bad design/usability practice?

like image 372
gaurav5430 Avatar asked Mar 02 '23 10:03

gaurav5430


1 Answers

The answer is actually quite simple in principle. When you click on the interactive element inside another interactive element which function should you trigger?

In your example if I click on Secondary CTA should it fire the function for secondary CTA or should it fire the function for the card?

The fiddle below should demonstrate the problem, tab into the first button and press enter, then tab into the CTA and press Enter.

Obviously you could work around this but I think it demonstates the point.

$('.card').on('click', function(){
    console.log("card");
});
$('.cta').on('click', function(){
    console.log("cta");
});
.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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<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" tabindex="0">
   Secondary CTA
  </div>
</button>

This principle then continues through to Screen Readers and other Augmentative and alternative communication (AAC) devices.

Should they take into account the parent element when describing the child element? Should they allow the use of Space to activate if you nest a checkbox within a <button>, should Enter then affect only the button or both?

like image 163
Graham Ritchie Avatar answered Mar 05 '23 17:03

Graham Ritchie