John
John

Reputation: 7049

Input element's width behaviour is mysterious

I have two input elements in a flexbox:

<div style="display: flex; width: 200px; background: black; padding: 2px">
  <input style="flex: 1" type="text" />
  <input style="flex: 1" type="text" />
</div>

(fiddle)

I want those to get the width of 200px evenly shared. They aren't however. Instead, they have have some mysterious default size. They don't listen to min-width either. They do listen to width though, so this does the desired thing:

<div style="display: flex; width: 200px; background: black; padding: 2px">
  <div style="flex: 1">
    <input style="width: 100%" type="text" />
  </div>
  <div style="flex: 1">
    <input style="width: 100%" type="text" />  
  </div>
</div>

(fiddle)

My question: why? And is this defined somewhere for some reason?

EDIT: This is what Chrome's inspector gives me:

enter image description here

EXTRA QUESTION:

As kukkuz pointed out, min-width is heeded - but only when the inputs are direct children of the flex container. Otherwise, they again like to be broader:

<div style="display: flex; width: 200px; background: black; padding: 2px">
  <div style="background: red; padding: 2px">
    <input style="flex: 1; min-width: 0" type="text" />  
  </div>
  <div style="background: red; padding: 2px">
    <input style="flex: 1; min-width: 0" type="text" />  
  </div>
</div>

(fiddle)

Bizarre. Is there a way to make this work without restorting to a width: 100%?

EDIT:

There is a way without resorting to a width: 100%: A nested flexbox. (fiddle)

<div style="display: flex; width: 200px; background: black; padding: 2px">
  <div style="background: red; padding: 2px; flex: 1; display: flex; min-width: 0">
    <input style="min-width: 0; flex: 1" type="text" />  
  </div>
  <div style="background: red; padding: 2px; flex: 1; display: flex; min-width: 0">
    <input style="min-width: 0; flex: 1" type="text" />  
  </div>
</div>

Upvotes: 2

Views: 468

Answers (2)

Asons
Asons

Reputation: 87251

Input element's width behaviour is mysterious
My question: why? And is this defined somewhere for some reason?

There is nothing mysterious here. An input element without a set width get its size from its size attribute, which defaults to 20.

Based on your 2nd fiddle, if you remove width: 100% and set the size to 5, you'll see it changes

<div style="display: flex; width: 200px; background: black; padding: 2px">
  <div style="flex: 1">
    <input style="" type="text" size="5" />
  </div>
  <div style="flex: 1">
    <input style="" type="text" size="5" />  
  </div>

Since the size attribute is based on n amount of character, it will be difficult to use it to match a parent's set width, so either use the CSS property width or one of the Flexbox properties flex-grow/flex-basis (nesting them included) to make them ...get the width of 200px evenly shared


EXTRA QUESTION:
As pointed out, min-width is needed - but only when the inputs are direct children of the flex container. Otherwise, they again like to be broader.
Bizarre.

Still nothing strange (or bizarre), as when they aren't flex items (children of a flex container), they yet again become standard input elements and my first explanation applies.

Is there a way to make this work without resorting to a width: 100%?

Yes, as you suggest your self, nest Flexbox so the inputs become flex items, though it appears unnecessary to do that when you simply can drop their parents (the extra div wrappers).


Based on the given comments, the min-width: 0 does work because a flex items default flex-basis is auto, which the specs. translate to:

auto

When specified on a flex item, the auto keyword retrieves the value of the main size property as the used flex-basis. If that value is itself auto, then the used value is content.

Here is a great answer (where the above comment is taken), that explain flex-basis a little deeper

Upvotes: 4

kukkuz
kukkuz

Reputation: 42372

Input elements have a default computed width due to the user agent / browser. So it responds to width.

You can set min-width: 0 - see demo below:

div {
  display: flex;
  width: 200px;
  background: black;
  padding: 2px;
}

div input {
  min-width: 0;
  flex: 1;
}
<div>
  <input type="text" />
  <input type="text" />
</div>

Upvotes: 1

Related Questions