Vertically align label with input - html

I am currently converting an old HTML form to not use tables. The label requires a fixed width, which I've achieved using an answer from this site. The current code is as follows:
HTML
<div id="form">
<label for="field1">Name </label>
<input type="text" id="field1" value="default name" />
</div>
CSS
label {
float: left;
width: 50px;
white-space: nowrap;
}
input {
display: block;
overflow: hidden;
width: *;
}
#field1 {
width: 150px;
}
Currently, the label is vertically aligned at the top. How can I vertically align the label and field to the centre?
Edit: I'm getting a lot of answers to basically pad my label into the correct position via a specified number of pixels. I don't want to do that as it's basically hard-coding and not true vertical alignment to the middle.
Following some advice I've received here, I've cleaned up my code some. See the above edited code.
I've tried vertical-align: middle; in label but it doesn't work. Please note that the user's platform will be IE.

If I get this right, You want the label and the input to vertically center align W.R.T each other and not the page. For that, there are couple of ways.
The Flexbox Way
If you want to use something new from the CSS world and be future ready, use flexbox. Example -
.fieldHeading {
width: 50px;
}
.fieldSpan {
overflow: hidden;
}
#field1 {
width: 150px;
}
/*flexbox approach.
* height and background added for clarity.
*/
#form {
height: 100px;
background: #bada55;
display: flex;
align-items: center;
}
<div id="form">
<label for="field1" class="fieldHeading">Name </label>
<span class="fieldSpan"><input type="text" id="field1" value="default name" /></span>
</div>
The vertical-align Way
This works well when you have both the label and the input on one line as inline-block elements. Example -
.fieldHeading {
width: 50px;
vertical-align:middle;
}
.fieldSpan {
overflow: hidden;
vertical-align:middle;
}
#field1 {
width: 150px;
}
<div id="form">
<label for="field1" class="fieldHeading">Name </label>
<span class="fieldSpan"><input type="text" id="field1" value="default name" /></span>
</div>
The height & line-height Duo
This works well too but if your label is big and has the possibility of wrapping into multiple lines, it's gonna look terrible. Example -
.fieldHeading {
width: 50px;
}
.fieldSpan {
overflow: hidden;
}
#field1 {
width: 150px;
}
/*line-height and height be same for parent
* background added for clarity.
*/
#form {
line-height: 40px;
height: 40px;
background: #bada55;
}
<div id="form">
<label for="field1" class="fieldHeading">Name </label>
<span class="fieldSpan"><input type="text" id="field1" value="default name" /></span>
</div>
I hope these help you not only in this problem but for all other vertical alignment problems.

You can use line-height or margin-bottom until you get satisfactory results.
Example
#form label {
line-height:1.4;
margin-bottom:2px;
}
This will apply the selector to all labels under the form. If you want to be specific, you can use the specific css class like .fieldHeading instead of #form label.

Do you need like this?
<div id="form">
<div class="valign">
<label for="field1" class="fieldHeading">Name </label>
<span class="fieldSpan"><input type="text" id="field1" value="default name" /></span>
</div>
</div>
<style>
.fieldHeading {
float: left;
width: 50px;
}
.fieldSpan {
display: block;
overflow: hidden;
width: *;
}
#field1 {
width: 150px;
}
#form {display: table;height:100%;}
.valign {
display: table-cell;
vertical-align: middle;
}
</style>

I think, solution margin-bottom, use whatever px you want
.fieldHeading {
float: left;
width: 50px;
margin-bottom: 3px;
}

Use:
.fieldHeading {
display: inline-block;
width: 50px;
vertical-align: middle;
}
#field1 { width: 150px; }
Let span be an inline type.
You don't really need the span for enclosing your input element.

Related

How do I align flexbox items to the baseline on a textarea input

I have a very simple input form. I want to align the labels with the input controls so they are at the same level.
I've decided to use align-items: baseline because no matter what the padding, height, etc, it will always align correctly. But, for some reason, when using it with an input of type textarea it does NOT align to the baseline, it aligns at the bottom. Why?
Sure, I can fix it using self-align and padding-top for the textarea, but that defeats the purpose of having something flexible without the need of fixing the padding in some inputs.
I just need to understand to logic, or is this is a bug/known issue?
* {
margin: 0;
padding: 0;
}
form {
width: 500px;
margin: 0 auto;
background-color: #e4e4e4;
}
form .control ~ .control {
margin-top: 20px;
}
.control {
display: flex;
align-items: baseline;
}
.control>div:nth-child(1) {
flex: 0 1 150px;
text-align: right;
padding-right: 20px;
}
.control>div:nth-child(2) {
flex: 1;
}
.control input,
.control textarea {
width: 100%;
padding: 20px;
}
.control textarea {
height: 100px;
}
<form>
<div class="control">
<div>
<label>Label goes here</label>
</div>
<div>
<input type="text" name="pretitle" value="">
</div>
</div>
<div class="control">
<div>
<label>Article</label>
</div>
<div>
<textarea name="article"></textarea>
<p class="explain sub">HTML allowed</p>
</div>
</div>
<div class="control">
<div>
<label>Label</label>
</div>
<div>
<input type="text" name="pretitle" value="">
</div>
</div>
</form>
https://jsfiddle.net/bnaL94u6/13/
The problem is not the textarea but the padding you are adding to both input and textarea, in textarea, you won't notice the it grows because 20pxx2 (40px) is not higher than 100px, but the input itself without the padding has only 19px, and when you add 40px of padding it will have a total height of 59px. and the the label will align in the middle of those 59px

How do I align my search-input and submit-button to the center of the page?

Sorry, I know this is super basic but I've been through my coding reference books all day and I think my mind's a little buggered. I need to get BOTH the input field AND the "submit" button in one line, in the center of the page, similar to Google.
.logo {
width: 50%;
display: block;
margin: auto;
}
.input-fields {
padding: 3%;
width: 40%;
display: block;
margin: auto;
font-size: 90%;
}
.submit {
padding: 3%;
width: 15%;
}
<header>
<img class="logo" src="OnSaleTodayMobile.png" alt="OnSaleToday.co.za">
</header>
<div class="form-wrapper">
<form class="center">
<input class="input-fields" name="search" type="text" placeholder="Search for anything...">
<input class="input-fields submit" name="find" type="submit" value="Find">
</form>
</div>
The problem I'm getting is that the button is stacking underneath the text-field. What am I missing out?
Well Google has it vertically and horizontally aligned so you should try something like this (simplified version):
* {margin: 0; padding: 0; box-sizing: border-box}
html, body {width: 100vw; height: 100vh}
body {
display: flex;
justify-content: center;
align-items: center;
}
.align-me {
display: flex;
flex-direction: column;
align-items: center;
}
.align-me > .form-wrapper > .center {
display: flex;
}
<div class="align-me">
<header>
<img class="logo" src="OnSaleTodayMobile.png" alt="OnSaleToday.co.za">
</header>
<div class="form-wrapper">
<form class="center">
<input class="input-fields" name="search" type="text" placeholder="...">
<input class="input-fields submit" name="find" type="submit" value="Search">
</form>
</div>
</div>
But their design is not responsive and this is.
What you are seeing is the default behaviour of display:block.
Using display:inline-block will make them block elements so you can add padding, etc, but make them inline so they will appear beside each other (assuming they fit, and other styles don't change the default behaviour).
Just change the display from block to inline-block in your CSS here:
.input-fields {
[...]
display:inline-block;
}
Working snippet:
.logo {width: 50%; display:block; margin:auto;}
.input-fields {
padding:3%;
width:40%;
display:inline-block; /* change this from block to inline-block */
vertical-align: middle; /* this will help with any vertical alignment issues */
margin:auto;
font-size:90%;
}
.submit {
padding:3%;
width:15%;
}
/* Add this this to center your inputs -
you included the "center" class in your HTML but not it in your CSS */
.center { text-align:center}
<header><img class="logo" src="OnSaleTodayMobile.png" alt="OnSaleToday.co.za"/></header>
<div class="form-wrapper">
<form class="center">
<input class="input-fields" name="search" type="text" placeholder="Search for anything..."/>
<input class="input-fields submit" name="find" type="submit" value="Find"/>
</form>
</div>
You are missing a
display: inline-block;
on the elements you want to display in line. You currently have 'display: block;' This will push elements on to there own line.
You may also want:
vertical-align: middle;
To make them vertically aligned relative to each other.
To make sure they both stay dead center in the page put them all in a container (or just use your existing form container) and style it like:
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
text-align: center;
This will ensure no matter what the screen size is the container is in the middle both vertically and horizontally.

Why does the font-size of an input breaks the inline-block alignment?

I recently stumble over the problem where I had to align to inputs next to each other which had slightly different font-size parameter. It turns out that is breaks the alignment of the input elements.
Here an exaggerated example to show the problem:
div input {
display: inline-block;
width: 100px;
height: 34px;
}
.field1 {
font-size: 50px;
}
<div>
<input class="field1" type="text" value="test">
<input class="field2" type="text" value="test">
</div>
What is the best way to fix that? How do I align the two input elements in one line next to each other?
vertical-align: top; seems to help solve this problem. I added only that rule which will align the input elements to the top of its parent container (the div in this case).
div input {
display: inline-block;
width: 100px;
height: 34px;
vertical-align: top; /* added */
}
.field1 {
font-size: 50px;
}
<div>
<input class="field1" type="text" value="test">
<input class="field2" type="text" value="test">
</div>

Responsive input field and submit button using display:table-cell

I am trying to have the input field and the submit button stretch across the screen in the same row. Basically so the submit button does not ever go below the input field. Not even sure if I need to add an extra or not. I know that I have seen a way to have a responsive input field and submit button using display:table-cell, but I have not been able to find it lately. Any help would be appreciated.
**EDIT
I added: margin-left: -8px; to the submit button and that did the trick. Not sure if there is a better way but this works. Any other ways would be appreciated as well.
#div1{
display:table;
width:100%;
}
#div2{
display:table-cell;
}
input[type="email"].form-control {
width: 80%;
padding: 0px;
margin: 0px;
}
input[type="submit"].btn.btn-primary {
width: 20%;
padding: 0px;
margin: 0px;
margin-left: -8px;
}
<div id="div1">
<div id="div2">
<input type="email" name="EMAIL" class="form-control"
placeholder="Enter your E-mail Address">
<input type="submit" value="Subscribe" class="btn btn-primary">
</div>
</div>
Are you Trying to achieve something like this using display:table-cell ?
<div id="div2">
<input type="email" name="EMAIL" class="form-control"
placeholder="Enter your E-mail Address">
<input type="submit" value="Subscribe" class="btn btn-primary">
* {
box-sizing: border-box;
}
#div2 {
display: table;
width: 100%;
}
#div2 > * {
display: table-cell;
}
#div2 > input[type='email'] {
width: 80%;
}
#div2 > input[type='submit'] {
width: 20%;
}
the key is box-sizing: border-box; you can write it just for your desired elements
https://jsfiddle.net/uw4u6ta5/3/
The line feed between the two s creates a space between them on the page. You have to remove the line feed, or use this trick :
<input type="email" name="EMAIL" class="form-control" placeholder="Enter your E-mail Address"><!--
--><input type="submit" value="Subscribe" class="btn btn-primary">
Also you have to remove border because it has 2px border so it's width is 20%+80%+ 2px+2px+2px+2px(left and right for two inputs)
use
border:0;
check this updates jsfiddle please
Check this post remove spaces between inputs
You really don't need two divs wrapping your inputs for this. You need to set the div to white-space: nowrap; to keep your inputs on one line. Simply set your inputs to width: 50%; or you may choose any other combination targeting each input specifically.
#div2 {
display: block;
margin: 0 auto;
width: 100%;
white-space: nowrap;
}
input {
display: inline-block;
width: 50%;
}
If you want the input to be 80% and the button to be 20% you need to target them individually with your classes.
.form-control {
display: inline-block;
width: 80%;
margin: 0;
padding: 0;
}
.btn-primary {
width: 20%;
margin: 0 auto;
padding: 0;
}
(JSFiddle) Updated

Input label on two lines next to input field

I want to have one label that is associated with the input field. Some of the labels need to go on more than one line. However, I am not able to view the text. What I am trying to achieve is shown below:
Label 1 <input />
sub text for label 1
The code I currently have is as follows:
<div class="row">
<label for="height">Height (help text here)</label>
<input name="height" id="height" ... />
</div>
CSS:
form { width: 100%; overflow: hidden; margin-top: -20px;}
form .row { height: 100%; overflow: hidden; padding-left: 140px; width: 295px; line-height: 30px; position: relative; margin-bottom: 6px; }
form label { position: absolute; top: 0; left: 0; line-height: 32px; text-align: left; width: 110px; font-size: 14px; display: inline-block}
There are a few rows that need to be formatted like this. Thank you for any help you can provide.
<div class="row">
<label for="height">Height <br /><span>(help text here)</span></label>
<input name="height" id="height" ... />
</div>
label {
display: block;
float: left;
}
make the label a block element so you can put a br. not a good solution also but it works :P
Try this :
<div class="row">
<label for="height">Height (help text here)</label><input name="height" id="height" ... /><br/>
<label for="height">Sub text</label>
</div>
It may be a workaround to your issue, but not a perfect solution
How about:
<div class="row">
<label for="height">Height</label>
<input name="height" id="height" ... />
<label for="height" class="help">help text here</label>
</div>
And CSS:
.row label {
display: inline-block;
width: 40%;
}
.row input {
display: inline-block;
width: 50%;
margin: 0 0 0 5%;
}
.row label.help {
display: block;
}
JS Fiddle demo.