23

I'm trying to understand the reason behind this problem:

What's the underlying reason behind <button> or <input> elements not behaving like other elements when set to display:block!

I'm not looking for workarounds to fix this problem, so please don't point me to this answer because it doesn't answer the question.

Here's a js-fiddle that illustrates the problem

Update 1: @Pete is correct, the default size attribute of an element is what sets the size even on block, as you can in this fiddle the size and cols attribute of <input> and <textarea> changes their width. That solves part of my question.

With that in mind, my question is now, why is the <button> element not behaving like other block elements? It's a mystery to me!

Community
  • 1
  • 1
Julian Krispel-Samsel
  • 7,512
  • 3
  • 33
  • 40
  • I am also trying to understand why setting `display: block` doesn't automatically stretch button to full width. The accepted answers don't answer the question at all, but rather sidestep the issue by specifying `width: 100%`. – kumarharsh Dec 28 '18 at 13:33
  • Possible duplicate of [Why doesn't "display: block" & "width: auto" stretch a button to fill the container?](https://stackoverflow.com/questions/27605390/why-doesnt-display-block-width-auto-stretch-a-button-to-fill-the-contai) – kumarharsh Dec 28 '18 at 13:56

3 Answers3

14

Button, Input and other form elements are actually replaced elements - see this answer: HTML5: Non-replaced vs. replaced element?

Additionally, button and input are inline elements. Thus, reading the MDN docs regarding visual formatting here: https://developer.mozilla.org/en-US/docs/Web/CSS/Visual_formatting_model, as well as the w3c docs here: https://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width, you can conclude that for replaced inline elements:

If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.

Therefore, button and input have an intrinsic width set to their content (or the size attribute on input, if used). That's why just specifying display: block doesn't do anything to the size of a button or input. You also have to override the intrinsic width of the elements.


Update: While researching more after answering this question, I found a much older answer which goes into much more detail about this same issue. You can find it here: https://stackoverflow.com/a/27605483/630170.

kumarharsh
  • 18,961
  • 8
  • 72
  • 100
6

I think that a default value is assigned to the size attribute of inputs which means unless you specifically override it, your width won't be 100%

If you look at the firefox specification and scroll down to the section about size, you can see that they have a default value of 20

I'm not sure about the properties for the button that cause that not to be 100% width when changed to block

Pete
  • 57,112
  • 28
  • 117
  • 166
2

Some elements like <input>, <textarea> or <button> have default styles included, like their border or, in your example, their size. I think the reason is, that HTML has still to be usable with the simplest markup and does not require any styling from css (or inlined attributes) to work.

The fact that display: block does not change this behaviour is, that an input field already is a block element. But in contrast to most other elements it does have a default value on the width attribute which is not 0.

The reason I think is pretty simple: If you create an <input> field and use no css or styling, you simply wouldn't see it, like you do not see an unstyled <div>.

Garrin
  • 541
  • 1
  • 3
  • 8