HTML spec is unclear about how buttons are sized in non-inline contexts (and browsers disagree) · Issue #2948 · whatwg/html (original) (raw)

The HTML spec says this about button rendering:

The button element expected to render as an 'inline-block' box
https://html.spec.whatwg.org/multipage/rendering.html#the-button-element-2

And this about <input type="button"> rendering:

An input element whose type attribute is in the Submit Button, Reset Button, or Button state is expected to render as an 'inline-block' box
https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-button

Most other form controls (e.g. checkboxes) have similar language. And in this HTML spec-text, inline-block is just a link to the CSS definition for display:inline-block.

So, my question: how should these elements render (and be sized) if they've been styled with display:block (either by directly setting it, or by floating/positioning)? In particular, should browsers apply the CSS sizing rules that apply to non-replaced block-level boxes in that case? (and fill the container, if the element has width:auto) Or should browsers apply the sizing rules for replaced block-level boxes?

From my testing, Firefox, Chrome, and Safari seem to size form controls as replaced elements (whether they're inline-level or block-level), which makes sense to me, but which seems to disagree with the HTML spec (which lists "form controls" in the "replaced elements" section at https://html.spec.whatwg.org/multipage/rendering.html and which seems to only specify image-typed input elements as being explicitly replaced).

Edge/IE [edit: and also Safari, actually] also does this in some cases, but they don't in one special case, so I'm not sure whether they consider these elements to be replaced or not. Here's a testcase: https://jsfiddle.net/ap6sb9oo/
Edge (and IE) disagree with all other browsers about the third line there -- they render the button as the width of the full viewport, which is only correct (per CSS) if the element is non-replaced. (But if they view the element as non-replaced, then I don't see why they'd give it the shrinkwrap treatment when it is display:block).