Why does input field width grow with number of inputs (flexbox)? - html

I'm implementing a form which has multiple sections with different numbers of input fields. When using display: flex on the parent div and 100% width on the input fields, I get different widths calculated, depending on the number of input fields inside the form.
When using display: block, everything works as intended.
<section>
One input field.
<div>
<form action="">
<input type="text">
</form>
</div>
</section>
<section>
Two input fields.
<div>
<form action="">
<input type="text"> <!-- each input field is double as wide as in the first section! -->
<input type="text">
</form>
</div>
</section>
section {
background: lightgrey;
width: 1100px;
}
div {
background: red;
display: flex;
}
form {
background: blue;
box-sizing: border-box;
}
input {
box-sizing: border-box;
width: 100%;
margin: 0.3125em 0 0.625em;
}
Codepen link with example
Is this supposed to be normal flexbox behavior? Am I missing something?
Thanks for any help!

Simply remove width:100% and you will better understand:
section {
background: lightgrey;
width: 1000px;
}
div {
background: red;
display: flex;
}
form {
background: blue;
box-sizing: border-box;
}
input {
box-sizing: border-box;
margin: 0.3125em 0 0.625em;
}
<section>
One input field.
<div>
<form action="">
<input type="text">
</form>
</div>
</section>
<section>
Two input fields.
<div>
<form action="">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
Three input fields.
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
Four input fields.
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>
The inputs are defining the width of the blue box and then this width will be the reference of the width: 100%; making all the input to be full width of it.
Basically, a percentage value need a reference so the width of the blue box is first calculated considering the content and then the input will use that width as reference.
This can also happen with simple inline-block elements
section {
background: lightgrey;
width: 1000px;
}
div {
background: red;
display: inline-block;
}
form {
background: blue;
box-sizing: border-box;
}
input {
box-sizing: border-box;
width:100%;
margin: 0.3125em 0 0.625em;
}
<section>
<div>
<form action="">
<input type="text">
</form>
</div>
</section>
<section>
<div>
<form action="">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>
More details about percentage sizing here: https://www.w3.org/TR/css-sizing-3/#percentage-sizing
You can find an explicit example of such behavior:
For example, in the following markup:
<article style="width: min-content">
<aside style="width: 50%;">
LOOOOOOOOOOOOOOOOOOOONG
</aside>
</article>
When calculating the width of the outer <article>, the inner <aside> behaves as width: auto, so the <article> sets itself to the width of the long word. Since the <article>’s width didn’t depend on "real" layout, though, it’s treated as definite for resolving the <aside>, whose width resolves to half that of the <article>.
When using display: block, everything works as intended.
Simply because the width calculation of block element is different and doesn't depend on the content unlike for inline-block elements or flex items where the content define the width

You are setting display: flex CSS property on wrong element, You need to set it on form instead of div,
When you set display: flex on div them form become the flex item not the inputs, Therefore none of the flex-item behaviour comes to input fields.
With following CSS it will work fine
section {
background: lightgrey;
width: 1000px;
}
div {
background: red;
display: flex;
}
form {
background: blue;
display:flex;
box-sizing: border-box;
}
input {
box-sizing: border-box;
width: 100%;
margin: 0.3125em 0 0.625em;
}
For more details refer to Flex tutorial

With display: block on the main containers (div), the form element – the child of the div – automatically occupies 100% width of its parent.
With display: flex on the main containers, the form element defaults to flex-basis: auto, which is the width of its content.
So if you want the same behavior with display: flex, add flex: 1 0 0 (aka flex: 1) to the form elements. This tells them to take full width of their parents, like display: block.
section {
background: lightgrey;
width: 1000px;
}
div {
background: red;
display: flex;
}
form {
flex: 1; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
background: blue;
box-sizing: border-box;
}
input {
box-sizing: border-box;
width: 100%;
margin: 0.3125em 0 0.625em;
}
<section>
One input field.
<div>
<form action="">
<input type="text">
</form>
</div>
</section>
<section>
Two input fields.
<div>
<form action="">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
Three input fields.
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>
<section>
Four input fields.
<div>
<form action="">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</form>
</div>
</section>

Related

Aligning Web Forms

I have two forms that I want to align. I was able to figure out how to align the height, but I can't get the width to work the way I want.
In my situation, I want the left box to fill in the remaining space. Using 'auto' just fills in the space to fit the contents. So instead of an expanding form, there is a gap between the two forms.
The reason I require this is I also have PHP around this form. There is a flag that dictates whether or not the second form shows up. So if there is only one form, I want it to expand the entire space. If there is two forms, I want them to share the space.
The way I thought of doing this would be to set the right form to a specific width and have the left form mold to whether or not anything else exists. I just can't figure out how to get the left form to expand itself without specifying an exact width.
I've included the HTML and CSS below as well as a JSFiddle reference.
HTML
<div class="section">
<div class="container">
<form>
<fieldset class="left">
<legend>PC Management</legend>
<div>
<input type='submit' value='Backup' />
<input type='submit' value='Backup' />
<input type='submit' value='Backup' />
</div>
</fieldset>
</form>
<form>
<fieldset class="right">
<legend>PC Management</legend>
<div>
</div>
</fieldset>
</form>
</div>
</div>
CSS
.section {
margin: 0 auto;
text-align: center
}
.container {
height: 100px;
width: 500px;
}
.container form, .container fieldset, .container input {
height: 100%;
display: inline;
}
.left {
width: auto;
float: left;
}
.right {
width: 40%;
float: right;
}
display: flex will get you the dynamic resizing that you want without needing any JavaScript:
.section {
margin: 0 auto;
text-align: center
}
.container {
height: 100px;
width: 500px;
display: flex;
}
.container form {
flex: 1 1 auto;
}
.container form, .container fieldset, .container input {
height: 100%;
}
<div class="section">
<div class="container">
<form class="left">
<fieldset>
<legend>PC Management</legend>
<div>
<input type='submit' value='Backup' />
<input type='submit' value='Backup' />
<input type='submit' value='Backup' />
</div>
</fieldset>
</form>
<form class="right">
<fieldset>
<legend>PC Management</legend>
<div>
</div>
</fieldset>
</form>
</div>
</div>
http://jsfiddle.net/eeLfx9d6/1/

Prevent textarea from scaling fieldset

I have a simple form with a textarea input inside of it. When I scale the textarea it pushed the fieldset boundary with it. How can I untie the textarea scale from the fieldset scale. I want this only to apply to the horizontal scale.
HTML
<form>
<fieldset>
<legend>Description</legend>
<label>Name</label>
<input type="text">
<p></p>
<label>Describe the object</label>
<textarea></textarea>
</fieldset>
</form>
CSS
textarea {
display: block;
max-height: 200px;
max-width: 350px;
}
jsfiddle
Add max-height to the fieldset, it will take care of the height.
It won't work with the width so you will have to work around it and wrap your text area wit a div and set it's max-witdh to the value of your fieldset.
<h1>Form Demo</h1>
<p>
<form>
<fieldset>
<legend>User Information</legend>
<label>Sex</label>
<input type="radio"
name="sex"
id="male"
value="male"/>
<label for="male">Male</label>
<input type="radio"
name="sex"
id="female"
value="female"/>
<label for="female">Female</label>
</fieldset>
<fieldset class="DontGrow">
<legend>Description</legend>
<label>Name</label>
<input type="text">
<p></p>
<label>Describe the object</label>
<div class="DontGrowWidth">
<textarea></textarea>
<div>
</fieldset>
</form>
css:
body {
width: 400px;
margin-left: auto;
margin-right: auto;
font-family: sans-serif;
}
label:nth-child(2) {
font-weight:bold;
}
.DontGrow{
height:160px;
max-height:160px;
}
.DontGrowWidth{
max-width: 300px;
}
}
fieldset {
margin-top: 30px;
}
input {
display: block;
}
textarea {
display: block;
max-height: 200px;
max-width: 400px;
}
input[type=radio] {
display: inline
}
This question is keep on repeating
textarea {
resize: none;
}
How to disable resizable property of textarea?
Learn to explore and search first before asking question. Google it!
I solved my own problem by wrapping the textarea in a div container and restraining this container in size.
HTML
<div class="textareas">
<textarea></textarea>
</div>
CSS
.textareas {
width: 300px;
}

HTML submit button's size is smaller than 100%?

I have a little problem with a HTML form and its submit button:
<form action="login/login.php" method="post" style="margin-top: 10px;">
<input id="login" name="username" type="text" placeholder="Nutzername" />
<input id="login" type="password" name="passwort" placeholder="Passwort" />
<input id="login" type="submit" value="Anmelden" />
</form>
CSS:
input[type=text]#login, input[type=password]#login {
border: 1px solid #ccc;
display: block;
height: 20px;
text-align: center;
width: 100%; }
input[type=submit]#login {
display: block;
height: 20px;
text-align: center;
width: 100%;
}
Result: http://jsfiddle.net/jMTT3/72/
As you can see, the button is slighty smaller than those text boxes.. What am I doing wrong?
The default setting is for width to apply to the content box (excluding padding and border). As the padding is different, the outer width is different.
You want to add:
-moz-box-sizing: border-box;
box-sizing: border-box;
to at least both of them.
Alternatively, you can set the same padding and border to achieve the same effect.
EDIT: Working Fiddle

How can I align a div at the edge of a div above it when said div is using automatic positioning?

I have a <div>:
<div id="placeHolder" class="card"><h1> A title!</h1><p>Some text!</p> </div>
and a second <div> containing some text and a <form>:
<div id="inputFields"><h4 class="header middle">edit</h4>
<div id="inputs">
<form id="form-inputs"><br>
Label <input class="input" type="text"> Label <input class="input" type="text"><br>
Label <input class="input" type="text"> Label <input class="input" type="text"><br>
Label <input class="input" type="text"> Label <input class="input" type="text"><br>
</form>
</div>
</div>
I am using CSS to automagically center the first div right where I want it on the page:
.card {
width: 850px;
height: 350px;
margin-left: auto;
margin-right: auto;
margin-top: 150px;
left: auto;
top: auto;
background-color: lightgrey;
}
This is great because the <div> does a reasonably well job of keeping itself centered. However I now want to align the second <div> with the first one so that it is directly under it along the left edge.
That's what I can't figure out how to do. I tried setting the second <div> to:
#inputFields {
left: auto;
top: auto;
}
But that doesn't work. I'm not sure why, but I'm guess it is because I haven't set the height and width manually.
How can I align these two <div>s next to each other?
Example of what it looks like currently. Basically I want to position the second <div> under the first one along it's left edge.
You need to assign the same width to the second div and also give it auto margins like so:
#inputFields {
margin:0 auto;
width: 850px;
}
http://jsfiddle.net/LHkhG/embedded/result/

How do I make a text <input> tag as long as the div containing it?

I have a form input with a label next to it, like this:
<div id="loginbox">
<form>
<div>
<span>Username</span>
<input type="text">
</div>
<div>
<span>Password</span>
<input type="password">
</div>
<div>
<input type="submit" value="Login">
</div>
</form>
</div>
Then I have some CSS that sets up the width of the login box and the span fields, like so:
#loginbox {
border: 1px solid black;
width: 300px;
}
#loginbox span {
display: inline-block;
width: 80px;
text-align: right;
}
Here is the jsfiddle for this code:
http://jsfiddle.net/7TNNq/
Notice how the input boxes do not span the entire length of the div. How do I get it to expand fully?
You could put
#loginbox div input {
width: 70%;
}
it will expand to the edge of the div, but I'm sure there's a better way to go about it.
Hope this helps
See: http://jsfiddle.net/thirtydot/tgGLv/
CSS:
#loginbox {
border: 1px solid black;
width: 300px;
}
#loginbox label {
float: left;
width: 80px;
}
#loginbox span {
display: block;
overflow: hidden;
padding: 0 4px 0 0;
}
#loginbox span input {
width: 100%;
}
HTML:
<div id="loginbox">
<form>
<div>
<label>Username</label>
<span><input type="text"></span>
</div>
<div>
<label>Password</label>
<span><input type="password"></span>
</div>
<div>
<input type="submit" value="Login">
</div>
</form>
</div>
Here it is.
http://jsfiddle.net/7TNNq/35/
Or you can set fixed width as #spike suggested.