26

When I set display: block; and width: auto; on a button, I'd expect the button to stretch to fill the container as other block elements do. For some reason, it doesn't, at least not in latest Chrome.

When Googling around, I found a lot of people asking the same question, who were satisfied with an answer to "How do I stretch my buttons to fill the container?" That is not what I'm interested in. (I'm perfectly able to stretch my buttons any way I need.) Inspecting button properties, including the ones imposed by default by the browser didn't help me either.

I'd like to understand, what causes buttons to ignore display: block; width: auto; and stay horizontally sized based on their contents.


Here's a demonstration of what I mean:

button {
  display: block;
}
<button style="width: auto;">button with `display:block; width:auto;`</button>
<button style="width: 100%;">button with `display:block; width:100%`</button>

I'd expect the button with width:auto; to be stretched as well.


Just to be absolutely clear, the above is not a duplicate to this or any similar questions that only have answers describing the ways to stretch the elements in question.

The above is not a duplicate of this question either. Though the answer applies here as well, because apparently the issues with sizing of input and buttons have the same core cause, the question doesn't mention buttons at all. Furthermore, there seems to be some uncertainty on whether <button> is even a proper "replaced element". This post (arguably) well serves the purpose of leading users with an issue to its solution.

hon2a
  • 7,006
  • 5
  • 41
  • 55

1 Answers1

37

(Shameless copy of the answer at this source and possible dublicate, which extracted the information from this article.)

There are a few elements (<input>, <select>, <button>, <img>, <object>, and <textarea>) that are considered replaced elements whose appearance and dimensions are defined by an external resource. (e.g. the operating system, a plugin, etc).

Replaced elements can have intrinsic dimensions—width and height values that are defined by the element itself, rather than by its surroundings in the document. For example, if an image element has a width set to auto, the width of the linked image file will be used. Intrinsic dimensions also define an intrinsic ratio that’s used to determine the computed dimensions of the element should only one dimension be specified. For example, if only the width is specified for an image element—at, say, 100px—and the actual image is 200 pixels wide and 100 pixels high, the height of the element will be scaled by the same amount, to 50px.

Replaced elements can also have visual formatting requirements imposed by the element, outside of the control of CSS; for example, the user interface controls rendered for form elements.

With HTML5 you have a couple more of those like <audio> and <canvas> and some more.

Please note that - as you will see in the discussions in the comments - button is not really a replaced element defined by w3c. However it is behaving like one, which is discussed further in this article.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
ProblemsOfSumit
  • 19,543
  • 9
  • 50
  • 61
  • 1
    Great, thanks. It looks like my question is pretty much a duplicate of the one you linked. As I haven't been able to actually find that one when looking for it, I'll my question open. – hon2a Dec 22 '14 at 15:25
  • 1
    The problem is that ` – Alohci Dec 22 '14 at 15:45
  • @Alohci replaced elements are elements that get their style from outside of the stylesheet. All form elements have a default style, set by the browser. That includes `button`. – ProblemsOfSumit Dec 22 '14 at 15:52
  • Yes, but I'm not talking about its style, I'm talking about its *contents*. It's an element's contents that are *replaced*. See http://jsfiddle.net/w50u3kc5/ to see how a button's contents are not replaced. – Alohci Dec 22 '14 at 16:00
  • @Alohci I'm happy to be taught otherwise. Do you mind pointing me to the w3c specification of "replaced elements" and how `button` isn't one? – ProblemsOfSumit Dec 22 '14 at 17:56
  • 1
    Sure. First of all, understand that "replaced elements" is a CSS concept. [CSS 2.1 Section 3.1 Definitions](http://www.w3.org/TR/CSS2/conform.html#replaced-element) describes it, though not as clearly as one would like. It starts of though by saying "An element whose *content* is outside the scope of the CSS formatting model ...". A button's content is definitely subject to the CSS formatting model, as per my earlier jsfiddle. – Alohci Dec 22 '14 at 18:02
  • I see, you might be right. [Here](http://www.w3.org/TR/CSS21/conform.html) is the w3c definition. [Sitepoint](http://reference.sitepoint.com/css/replacedelements) specifically mentions buttons though. [This article](http://meyerweb.com/eric/thoughts/2007/05/15/formal-weirdness/) on the other hand discusses that `button` isn't a replaced element, but strangely behaves like one. You're right, I'll edit my answer to clarify. – ProblemsOfSumit Dec 22 '14 at 18:14
  • 3
    Historically speaking, the whole freaking point of the button tag was to give us something that wasn't a replaced form input of `type="button"` we could use that gave us complete styling control. Treating it as a replaced element forces us to go back to semantically misusing A tags or divs in scenarios where we need that level of control – Erik Reppen Dec 01 '16 at 16:27
  • Still about a hundred times better than input type=button. :) – Jen May 04 '17 at 05:45