CSS to Replace Table Layout for Forms - css

I've looked at other questions and am unable to find the solution to this. Consider this image: mockup http://img201.imageshack.us/img201/935/image2h.png
I want to wrap divs and stack them vertically. The GREEN div would be a wrapper on a line. The BLUE div would contain an html label and maybe icon for a tooltip. The ORANGE div would contain some sort of entry (input, select, textarea).
Several of these would be stacked vertically to make up a form. I am doing this now, but I have to specify a height for the container div and that really needs to change depending on the content - considering any entry could land there. Images and other stuff could land here, as well.
I have a width set on the BLUE div and the ORANGE is float:left. How can I get rid of the height on divs and let that be determined by content? Is there a better way? Changing all to something else would be difficult and would prefer a way to style all elements or something.
The code I'm using is like:
<div class=EntLine>
<div class=EntLbl>
<label for="Name">Name</label>
</div>
<div class=EntFld>
<input type=text id="Name" />
</div>
</div>
The CSS looks like:
.EntLine {
height: 20px;
position: relative;
margin-top: 2px;
text-align: left;
white-space: nowrap;
}
.EntLbl {
float: left;
width: 120px;
padding: 3px 0px 0px 3px;
min-width: 120px;
max-width: 120px;
vertical-align: text-top;
}
.EntFld {
float: left;
height: 20px;
padding: 0px;
width: 200px;
}

Well, for a start I think you could use less mark-up to achieve your aim. You might have a good reason for wrapping a div around every element of your form, but if it's just to force a single label-input pair to each line then you can nest the input inside the label tag:
<label for="Name">Name
<input type="text" id="Name" />
</label>
This way you can use a simple:
label {display: block; }
to force each pair to their own line. This would also remove the need to float the labels, which removes the need to specify the height of any containing element.
You can still apply multiple classes to the relevant fields/labels, but it's far less trouble. Unless I'm really missing something.
Failing all of that, you could simply add an empty div (or other element), after the last of your fields and style with:
#empty_element {
disply: block;
height: 0;
clear: both; /* to force the parent element to expand to contain this element and, by extension, any non 'position:absolute' siblings that precede it in the mark-up */
visibility: hidden;
}

Related

How can I move my pseudo element checkbox based on text direction?

A common way to make a custom looking checkbox element is to hide the browser's default checkbox and create a pseudo element on the checkbox's label for your custom looking one:
.myclass::before {
<Some styles for the custom looking checkbox>
}
Usually the rendered HTML ends up looking something like this:
::before
<label class="myclass">text</span>
I am having trouble positioning my checkbox based on text direction though. For ltr languages (Like English) Having the checkbox appear ::before the label text makes sense, but it looks awkward in rtl languages (Like Hebrew). Making an identically styled ::after pseudo element fixes my problem, but I don't know how to only apply one CSS style over the other based on text direction. There doesn't seem to be any way in CSS alone to detect an element's computed text direction (unless you're Firefox?)
Any suggestions?
div{
margin: 10px 10px 30px;
}
label{
position: relative;
cursor: pointer;
display: block;
}
span{
content: '';
display: block;
background: #fff;
width: 15px;
height: 15px;
border: 1px solid red;
position: relative;
top: 20px;
}
label strong{
color: #fff;
display: block;
position: relative;
top: -15px;
}
input:checked + strong{
color: red;
}
<div>
<label>
<span></span>
<input type="checkbox"> English
<strong>X</strong>
</label>
</div>
<div>
<label dir="rtl">
<span></span>
<input type="checkbox"> العَرَبِيَّة
<strong>X</strong>
</label>
</div>
I would add a class to the body element, say 'set-rtl'/'set-ltr', assuming you know you're on rtl mode, and then style your elements based on the body class.
In your example it will be:
.set-rtl .myclass::after{
<Some styles for the custom looking checkbox>
}
.set-ltr .myclass::before{
<Some styles for the custom looking checkbox>
}
Another option is to create a different CSS file for each mode.
So I had 2 problems.
My display style needed to be set to inline-block
I had to change my sudo-element's position from absolute, to relative which meant:
removing the initial label's padding (This was space that was set aside for the check box)
Add an equal amount of left and right padding to the check box
vertical-align: middle;
THEN the checkbox flowed ltr or rtl depending on the language just like it's text does.
Basically it boiled down to the fact that I was treating the checkbox as a very separate, specially handled thing.

Div vertical-align in a gwt-page

I am trying to set a div element on the right top of a web-page which contains a span, a label and a button. I want to bring all the elements in alignment regarding the vertical high (preferably at the middle of the div element). However vertical-align: middle does not work as the elements are cling to the top of the div. They are probably influenced by an external div or Panel (since I use gwt). Should I interfere in the default attributes of the gwt widgets? What other solution can you suggest?
The code:
<div class="{style.topRightDisplay}">
<span style="float:left;">Eingeloggt als: </span>
<g:HTML ui:field="loginHTML" addStyleNames="{style.loginHTML}"></g:HTML>
<g:Button ui:field="logoutButton" addStyleNames="{style.button}">Logout</g:Button>
</div>
.button {
float: right;
margin-right: 15px;
}
.loginHTML {
float: left;
}
.topRightDisplay {
float: right;
height: 20px;
width: 200px;
vertical-align: middle;
}
You misunderstand the purpose of vertical-align. See the explanation of vertical-align on MDN
You need to apply vertical-align to the child elements, not the parent.
Without knowing what your markup looks like, I suggest this:
.topRightDisplay input,
.topRightDisplay button,
.topRightDisplay span{
vertical-align: middle;
display: inline-block;
}
You should also remove the floats. Floats make an item render as a block-level element, which means vertical-align won't work.
Instead you can use display: inline-block. You may need to change the order of the elements in hmtl to get the result you want.

How can I expand this <input> tag?

This is a simplified version of my question earlier today since I didn't get a satisfactory reply.
I have a HTML and CSS code as in this Fiddle: http://jsfiddle.net/wNGHz/
How can I make the <input> resize automatically when its parent frame is resized?
Notes:
I prefer to use only CSS rather than JavaScript.
The <input> should have 100px distance from left and right edges of the parent.
#thirtydot semantically I want to have a simpler HTML. I can wrap
<input> with <div> but it's just weird to add one more element for the
sole purpose of styling another one. I was wondering if anyone has a
better solution.
Unfortunately, there is no better way. It has to do with the fact that input is a replaced element, which means it behaves differently to non-replaced elements such as div.
One difference is that position: absolute; left: 0; right: 0 won't work in the same way on an input as it does on div (except in WebKit).
The best workaround is to wrap the input in a div:
http://jsfiddle.net/thirtydot/wNGHz/6/
<div class="inputContainer">
<input type="text" value="test" />
</div>
.inputContainer {
position: absolute;
left: 50px;
right: 50px;
}
input {
width: 100%;
background-color: red;
color: white;
border: none;
}
When you have input { width: 100%; }, it's usually a good idea to also add box-sizing: border-box, to make any padding and border on the input be counted inside the width: 100%: http://jsfiddle.net/thirtydot/wNGHz/7/
The only pure CSS way I know of is by adding a width in %: http://jsfiddle.net/PeeHaa/wNGHz/1/
You can do this better way.
<div class="inputContainer">
<input type="text" value="test" />
</div>
input {
width: 100%;
margin:0 100px;
}

float divs inside container, text leaks out the bottom of the container, I want it inside the container.

I have 2 divs inside a container, Each of the inside divs are floated to the left and right, I want to make 2 columns for data inside the main content div.
Currently, text leaks out the bottom of content-left and content-right, even though they are contained within content.
Here is a jsfiddle
<div id="content">
<div id="content-left">I want to put content in here<br/><br/><br/>This is outside? why? </div>
<div id="content-right">and more in here</div>
Maybe other content here, inside the content
</div>
And the CSS
#content-left{
width: 50%;
border: 1px dotted #aaa;
float: left;
}
#content-right{
width: 49%;
float: right;
border: 1px dotted #aaa;
}
#content{
background-color: #eee;
width: 95%; /* Width of Main Content Div, % for Fluid*/
height: auto;
max-width: 1350px; /*Max width, To wide on big monitor*/
margin: 0 auto;
padding: 10px;
padding-left: 20px;
padding-right: 20px;
}
Also, any tips about floating items would be great and might earn reps if I find them useful, I thought I had it mastered but obviously not! :P
You just need to add a clearing br inside the last div
Maybe other content here, but this should be below the 2 above divs in the rendered view.
<br style="clear:both;" />
</div>
http://jsfiddle.net/jasongennaro/sahbz/9/
This is happening because the floated elements are taken out of the document flow.
Currently, text leaks out the bottom of content-left and
content-right, even though they are contained within content.
You need to "clear/contain your floats", more information here: http://www.ejeliot.com/blog/59
One simple way to do that is to add overflow: hidden to #content.
See: http://jsfiddle.net/sahbz/8/
Pure CSS
.content:after {
clear: both;
content: '';
display: block;
}

Select inputs and text inputs in HTML - Best way to make equal width?

I've got a simple form like so (illustrative purposes only)...
<form>
<div class="input-row">
<label>Name</label>
<input type="text" name="name" />
</div>
<div class="input-row">
<label>Country</label>
<select name="country">
<option>Australia</option>
<option>USA</option>
</select>
</div>
</form>
My layout method using CSS is as follows...
form {
width: 500px;
}
form .input-row {
display: block;
width: 100%;
height: auto;
clear: both;
overflow: hidden; /* stretch to contain floated children */
margin-bottom: 10px;
}
form .input-row label {
display: block;
float: left;
}
form .input-row input,
form .input-row select {
display: block;
width: 50%;
float: right;
padding: 2px;
}
This all aligns quite nicely, except my select element (in Firefox anyway) isn't always the same width as my other input elements. It generally is narrower by a few pixels.
I've tried changing the width to a pixel size (e.g. 200px) but it has not made a difference.
What is the best way to get these to all have the same width? I hope it doesn't resort to me setting the select's width individually, or putting them into tables...
The solution is to specify box model for form elements, and browsers tend to agree most when you use border-box:
input, select, textarea {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
There's normalize.css project that aggregates such tricks.
padding will make the text be closer to the edge of the box.
try setting the margin to 0px, and if that seems right, play around with it (like just setting margin-left only)
Had same problems with 100% width table and cells, with a textbox (also with width at 100%) wider than the table cell.
This solved my problem in the css:
table td
{
padding-right: 8px;
}
Not the best solution ever, cause you probably get some additional space to the right side. But at least it's not hiding anymore!

Resources