Page 1 of 1

button's children - chrome behavior

Posted: 2018-07-26, 13:02
by pmuser2
Positioning one HTML element relatively to another without JS is done via nesting and absolute positioning.
Relative-to-another positioning can be useful to show a small dialog near a button, after clicking that button.
I know, HTML doesn't allow button to have interactive content (which includes button),
but I'm sure they meant visually-inside-a-button content. Absolutely positioned elements are usually perceived as separate.

In Palemoon (stable and alpha) and Firefox it's impossible to click a button in a dialog shown in aforementioned way.
Contrary, Chrome, Edge and IE11 are all allow it you.
IE11 has peculiarities with this: requires 'overflow: visible'; if source button is disabled, dialog buttons are visually disabled too - but at least it lets script go.
Chrome and Edge behave most naturally: they show a message normally and let you click a button in it.
(Edge doesn't allow you to inspect such message, but it doesn't matter much.)

Just test the following text and you'll see what I mean. Palemoon shows the message, but that's all, you can't click the button.
I suggest to change Palemoon behavior in such cases.

Code: Select all

<!doctype html><html lang="en"><meta charset="utf-8"><title>untouchable button</title>
<style>
#btn {
	position: relative;
	overflow: visible; /* for ie11 */
}
.msg {
	position: absolute;
	top: 100%;
	padding: .5rem;
	background: yellow;
}
</style>

<button id="btn" class="btn">btn</button>

<div id="templateMsg" class="msg" hidden><button>yes</button></div>

<script>
btn.onclick = function ()
{
	this.disabled = true;
	const msg = templateMsg.cloneNode (true);
	msg.removeAttribute ('id');
	this.appendChild (msg);
	msg.hidden = false;
}
</script>

Re: button's children - chrome behavior

Posted: 2018-07-26, 14:35
by Moonchild
The behavior in our browser is correct, as far as I can tell.

What happens here when clicking the button:
  1. You then create a new node by cloning a template which has the new button in it.
  2. You now have a node consisting of the div and embedded button that is not part of the document.
    Before inserting it into the document structure, you make sure to remove the id to prevent duplicate ids (Good!)
  3. You make this node part of the document by appending this node as a DOM child to the clicked button (Bad)
What you end up with is the yellow DIV and button being attached to the button as a child, that means from a DOM hierarchy perspective, the DIV and second button is inside the context of the button. (If you remove the "absolute" positioning you will see where, from a DOM perspective, the DIV is placed: inside the button.)
The document structure will be:

Code: Select all

<button>
  <div>
      <button>yes</button>
  </div>
</button>
This means you are trying to use interactive content inside a button, which, as you yourself stated already, isn't allowed by the HTML standard. It doesn't matter in that respect if it is visually placed outside of the button or not, because in the hierarchy of elements, it's a child node of the button. It's only considered a separate context from a layout perspective by making it absolutely positioned -- but that is not the document structure which is what matters here.
If Chrome and IE behave differently, then they are not adhering to the spec and that should be considered a bug...

If you want this to work, you should append the child node to a different element that is part of the document that is of a type that allows interactive content in its children.