CSS : Table with Labels and Text Boxes - html

I am trying to break the table crutch...
I want to place 3 "labels", "First", "Middle" and "Last" over 3 text boxes so that the labels are above the corresponding text boxes and the labels and text boxes are vertically aligned. In other words, I need a 3 columns table where the first row has 3 labels and the 2nd row has 3 text boxes in them and everything is left justified and I want ALL the columns widths to be identical and fixed.
How do I do this with w/o tables using only CSS?
I know that margin-left will give me a consistent distance between the groups, but how do I "carriage return" to the next line w.o using a Paragraph or a break tag, since the distance involved is really a function of the font, I imagine, instead of being able to "carriage return down" a specified number of pixels.
I know that display: block will put things on a new line, but that creates a break before and after. I just want a break "after."
I hope I explained it well enough.
Thanks.
Additional Edit:
I understand that perhaps I should not be avoid using tables for something that tables is good at, but if CSS had an attribute analagos to margin-left:10px but in a vertical direction AFTER performing a cariage return, the advantage of using CSS over tables is that I wouldn't have a million TR and TD tags in my markup.
Is there such a thing?

What you do is create your form fields this way:
<div id="form">
<div class="control">
<div class="label">
<label for="field1">Field 1</label>
</div>
<div class="field">
<input type="text" name="field1" id="field1">
</div>
</div>
...
</div>
with:
#form { overflow: hidden; } // this is important!
#form div.control { float: left; width: 33%; }
Now if one of those labels is larger the controls won't line up but this would be an example of where "pure" CSS falls shorts of what tables can do easily and naturally, which begs the question: why are you giving up on tables?
Note: Another answer along the same lines has suggested not wrapping the label and input in a div. This is a reasonable approach but you lose some expressive power. For instance, some things in CSS are only possible on block level elements. For example, you could change the above with:
#form, div.control { overflow: hidden; width: 600px } // this is important!
#form div.control { float: left; width: 200px; }
#form div.control div { float: left; width: 100px; }
and get your labels on the left, which you can't do quite as well without the wrapping inner divs.

HTML:
<div class="row">
<div class="column">
<label>Left</label>
<input name="left" />
</div>
<div class="column">
<label>Left</label>
<input name="left" />
</div>
<div class="column">
<label>Left</label>
<input name="left" />
</div>
</div>
CSS:
.row .column{
width: 200px;
float:left;
}
.row .column input,
.row .column label{
display:block;
}
You can now use CSS to style the textboxes and labels, so they look nice. Also notice how similar this example is to using tables, which goes to show that in some scenarios tables aren't evil, but the right way to go. If you want to align things in a grid, use tables.

Turns out that if you want to make a table of labels over input fields, the table element is fine to use.... If the table element is the clearest html code, why not use it?

Related

How to get this search-results-div to show up on top of content, without interfering with nearby float elements?

I have a tricky layout that I'm trying to add type-to-search to. (The actual code uses Angular, but it looks like my problem is just the CSS.)
https://jsfiddle.net/dowxw1dz/2/
In a single TD, there are two floating bits off to the right (a descriptive label, and a button unrelated to the label). The main part of the TD is a text input, which takes up the remainder of the space. I'm trying to enhance the input by making it show a div with search results below it, overlaying the stuff below the input.
The problem I'm hitting is that the div containing the input is overflow:auto, so when the search results show up, they just add a scrollbar to the input div (with the search results visible if you scroll), rather than showing the search results on top of the other content. I could fix this by changing the overflow to something else, but then the two floating elements to the right decide to get out of the way of the input.
How can I get the search results to show over the lower content, rather than being trapped in the input div with a scrollbar? Ideally, I want the search results to be exactly as wide as the input (which is going to be variable), but my first problem is just to get the search results to show without either shoving around the floating elements or shoving the results behind a scrollbar.
HTML:
<div style="width:600px;">
<input type="button" value="Button!" style="float:right; width:100px;"/>
<span style="float:right"> Category </span>
<div class="inputRow">
<input type="text" id="input"/>
<div class="searchResults">
Results!
</div>
</div>
</div>
<div style="width:600px;">
There's other stuff that goes here. The searchResults div should cover this without pushing it out of the way. (The search results will be clickable to pick something, and then it'll go away.)
</div>
CSS:
.searchResults {
position:absolute;
top:100%;
background-color: white;
border: 1px solid black;
z-index: 50;
display: none;
}
.inputRow {
position:relative;
overflow:auto;
}
input {
width: 98%;
}
div {
z-index: 0;
}
JS:
$("#input").change(function() {
$(".searchResults").show();
});
It seems you need to use position fixed instead of position:absolute, and assign top:7% it will work. It's a way around. Still can't figure out why position:absolute is not working. I'm yet in the learning phase.
.searchResults {
position:fixed; /* instead of : position:absolute;*/
top:7%; /* instead of : top:100%;*/
background-color: white;
border: 1px solid black;
z-index: 50;
display: none;
}
Fiddle here : https://jsfiddle.net/nithin_krishnan/dowxw1dz/5/
The solution was simply to ignore the input element, and put the results in the content below the input, instead.
Unfortunately, that meant that setting the width had to be done in JavaScript instead of simply relying on CSS to do the right thing. I ended up using $(".searchResults").width($("input").width()) in order to make the width of the results match the width of the input. (And I removed the top: 100% from the .searchResults CSS class.)
https://jsfiddle.net/dowxw1dz/7/
<div style="width:600px;">
<input type="button" value="Button!" style="float:right; width:100px;"/>
<span style="float:right"> Category </span>
<div class="inputRow">
<input type="text" id="input"/>
</div>
</div>
<div style="width:600px; position:relative;">
<div class="searchResults">
Results!
</div>
There's other stuff that goes here. The searchResults div should cover this without pushing it out of the way. (The search results will be clickable to pick something, and then it'll go away.)
</div>

Horizontally Align Labels with CSS

I've got an issue that I'd love to solve by using CSS without resorting to statically sizing my labels (but perhaps it isn't possible).
I have two labels per line, one for displaying a "title" and the other for displaying the associated "value". Here's how I'd like it to look:
This is similar to Align labels in form next to input but I'm wanting the second element per line left-aligned instead of the first one to be right-aligned. I tried modifying the accepted answer from that question and set the width of the "title" label, but that has no effect on my output. As I mentioned above, I'd rather not hard-code a width anyways, but I was hoping to get something working before trying to find a good, long-term solution that can account for larger "title" values.
Here's my current CSS (the classes should be self-explanatory):
.propertyTitle {
text-transform: uppercase;
width: 300px;/*Why doesn't this have any effect?*/
}
.propertyValue {
text-align: left;
}
And my current HTML:
<div>
<div>
<label class="propertyTitle">Hello:</label>
<label class="propertyValue">World</label>
</div>
<div>
<label class="propertyTitle">Goodbye:</label>
<label class="propertyValue">To All of the People in the World</label>
</div>
<div>
<label class="propertyTitle">I Want:</label>
<label class="propertyValue">These labels to line up</label>
</div>
</div>
The HTML can be modified as well, if that'd make it easier. To conform with best practices, I'd rather not use tables to make this work.
Here's a jsFiddle showing what I have now, what am I missing? Ideally this solution would work for IE8+ and Firefox, so unfortunately HTML5 and CSS3 elements are discouraged.
EDIT
To reiterate after the first two answers came in (that both solve my issue), is there a way to do this without hard-coding a width for my "title" labels?
grouping your divs and labels like so:
<div>
<div class="titleWrap">
<label class="propertyTitle">Hello:</label>
<label class="propertyTitle">Goodbye:</label>
<label class="propertyTitle">I Want:</label>
</div>
<div class="valueWrap">
<label class="propertyValue">World</label>
<label class="propertyValue">To All of the People in the World</label>
<label class="propertyValue">These labels to line up</label>
</div>
</div>
with the following CSS:
.propertyTitle {
display:block;
text-transform: uppercase;
width: auto;
}
.titleWrap{
display:inline-block;
}
.propertyValue {
display:block;
width:auto;
}
.valueWrap {
display:inline-block;
}
should give you the desired result without having to specify the widths
Check out this jsFiddle
try using display:inline-block on your labels
.propertyTitle {
text-transform: uppercase;
width: 300px;/*Why doesn't this have any effect?*/
display: inline-block;
}
by default label is an inline element. that's why width property doesn't apply to label.
to apply the width you have to convert the label into a block level element by using display:block.
I hope it clarify the answer.
so you have to use this CSS property in your code.
.propertyTitle {
text-transform: uppercase;
display:inline-block; /*this will make the label a block level element*/
width: 300px;/*Why doesn't this have any effect?*/
}
More modern version is display: inline-flex;

How to set all buttons in a controlgroup to the same height when some have two-row labels?

I want to create a row of multiple buttons to form a coherent block in jQuery Mobile. For this, I placed them in a horizontal controlgroup. This approach works well for simple labels, but now I want to have one or more buttons with two rows of text on them. For example:
<form>
<fieldset data-role="controlgroup" data-type="horizontal">
Left
Middle item<br/><sub>Second row</sub>
</fieldset>
</form>
Example on jsfiddle.
My problem is that the multi-row labels appear fine, but the other buttons on the row still have a width appropriate for a single-row label (or no label). The result looks like this:
How can I ...
make all the buttons have the same height?
center the one-row button labels vertically to the new height?
center the icons vertically?
You can Try this:
First Step : assign an id for your <fieldset>
<fieldset data-role="controlgroup" data-type="horizontal" id="t">
Second Step : changes in your css for the a tag
#t a {
float:none;
display:table-cell;
vertical-align:middle;
}
View the Demo http://jsfiddle.net/4qKkf/12/
This can be done using the display: table-cell; trick which allows you to give the links a uniform height and allows vertical centering by use of vertical-align
CSS:
a[data-role] {
display: table-cell;
float: none;
vertical-align: middle;
}
Example: http://jsfiddle.net/4qKkf/14/

How to put the <p> content inline with the <label>?

I run into a css issue.
I have a form, and inside it I want to show a label and some info in each line.
The html for the form is:
<form class="form_dialog">
</br>
<label>Status: </label>
<span><img src="images/check.png" alt="check mark" width="16" height="16"/></span>
</br></br>
<label>Type: </label>
<span>V1</span>
</br></br>
<label>Description: </label>
<div class="sp">16 Nodes - Test for long description.
This system is good in all cases. Max length is 100.</div>
</form>
The css for all the tags are:
form.form_dialog {float: left; clear: left;}
.form_dialog div {float:left; clear:left}
.form_dialog label {
display: block; float: left;
width: 12.0em; min-height: 2.0em; text-align: right;
}
.form_dialog span {
margin-left: 3.0em;
}
div.sp {
display:inline;
margin-left:3em;
margin-right:3em;
width:70%;
}
My prob here is that for the description info, I want to keep the text lines indented(each line starts from the same position) as well as inline with label. But cannot achieve it.
Any one can help on this? Thanks.
You are creating a table. You could use a table, or use two seperate elements, placed side by side inside of a containing .
<div class="container">
<div class="formContainer">
</div>
<div class="textContainer">
</div>
</div>
Then float each container and align your text using CSS.
Agreed with Trendy, also, since you starting using span tag, you should just use the span
<span>16 Nodes - Test for long description.
This system is good in all cases. Max length is 100.</span>

Is such alignment achievable without <table>?

My goal is an alignment as shown in the attached image (the fields on the left may have any width, but the ones on the right should begin at the same X coordinate).
Right now I am using a simple table code to achieve this:
<table><tr>
<td>Left1</td><td>Right 1</td></tr>
<tr><td>Left 2</td><td>Right 2</td></tr></table>
However, I've heard that using tables is generally bad. Is there a way I could achieve the same design using CSS? The website is being designed for mobile devices which might not support fancy CSS, so the code must be as simple as possible.
EDIT: since I still occasionally get a notification on this question from people who (presumably) are just starting out with HTML like I was when I made it, please refer to the accepted answer by B T as this is by far the best way to achieve this functionality. The question suggested as a "possible duplicate" (31 May 2016) does not currently offer the table-row/table-column CSS-based approach and requires you to do guess work.
I found a much easier way to do this by accident. Say you have the following:
<div class='top'>
<div>Something else</div>
<div class='a'>
<div>Some text 1</div>
<div>Some text 2</div>
</div>
<div class='a'>
<div>Some text 3</div>
<div>Some text 4</div>
</div>
</div>
You can align Some text 1 and Some text 2 using css table display styling like this:
.a {
display: table-row;
}
.a div {
display: table-cell;
}
The coolest thing is that as long as the 'top' div is NOT styled display: table, then other things like "Something else" can be ignored in terms of alignment. If the 'top' div IS styled display: table, then "Some text 1" will be aligned with "Something else" (ie it treats all its children like table rows, even if they have a different display style).
This works in Chrome, not sure if its supposed to behave this way, but I'm glad it works.
.a {
display: table-row;
}
.a div {
display: table-cell;
}
<div class='top'>
<div>Something else</div>
<div class='a'>
<div>Some text 1</div>
<div>Some text 2</div>
</div>
<div class='a'>
<div>Some text 3</div>
<div>Some text 4</div>
</div>
</div>
While it is possible to achieve the same with tables, it would be considered semantically incorrect to use a table for the purpose of layout. Especially since you can achieve the same using just a line or two of CSS.
Give your labels a fixed width (something larger than your longest label text).
<style>
label {
width: 100px;
display: inline-block;
}​
</style>
<label>Name</label>
<input type="text" />
<br/>
<label>Email Address</label>
<input type="text" />​
Example
Here, you could use this for getting the output required.
Using tables IMO is not bad practice, in fact they should be used where tabular data is required, or the format of data resembles a table.
However, designing a full page, or anything not to be displayed in a tabular format, using a table is discouraged, and is in fact very very wrong.
Here goes a sample using a non-table structure:
HTML :
<form>
<label for="name">Email: </label><input id="name" type="email" placeholder="#" />
<br/><br />
<label>Password: </label><input type="password" id="password" placeholder="*"/>
</form>
CSS:
label {
width: 80px;
display: block;
vertical-align: middle;
float:left;
clear:left;
}
input {
border-top-left-radius:5px;
border-bottom-right-radius: 10px;
background: #141414;
color: #fdd56c;
outline: none;
}
Here is an example
Yes, such alignment is possible. Using CSS classes, you can markup your HTML in such a way to achieve the same look of a table without the headache of using a table (or making the markup look ugly).
Using this CSS:
.label {
display: inline-block;
width: 100px;
}
.inputBox {
width: 200px;
}
and this HTML:
<span class="label">E-mail:</span><input type="email"></input><br>
<span class="label">Password:</span><input type="text"></input>
you'll get the layout you want.
To do this with IE7 support, change the CSS above to this:
.label {
display: block;
width: 100px;
float: left;
clear: left;
}
Then, add this line below the lines already shown:
<div style="clear: left"></div>
Example using IE7-compatible settings: http://jsfiddle.net/bbXXp/
True. I am learning it the hard way. I used table for alignment, and now, certain alignments are becoming bizzare in smaller screens (e.g. mobile phone, tablets etc). Hence, am switching over to div. Preferable use <div style="display:inline-block">...</div>, which will align automatically if the screen is smaller.
Hence, my advice is that Table should be used only for genuine tables, and not for aligning controls in a body.