views:

362

answers:

4

I'm trying to get this css layout to work with IE7 and I'm a bit stuck. Any thoughts on how I can get the form to look like it does in FF and Chrome without changing the page structure? I know there are some IE specific CSS hacks out there, but I'm not totally sure how to apply them.

In FF and Chrome the form correctly displays the form as follows:

title
first last
street
city state zip
occupation bday

In IE the form is all jumbled:

title last state zip
street 
city

CSS

...
form label  { float: left; margin: 0px 10px 0px 0px; }
form input  { width:100%; }
form select { width:100%; }

form label.field-title        { width: 50px; clear: left; }
form label.field-title select { width: 50px; }

form label.field-first { width: 150px; clear: left; }
form label.field-last  { width: 150px; }

form label.field-street{ width: 310px; clear: left; }

form label.field-city  { width: 150px; clear: left; }
form label.field-state { width: 70px; }
form label.field-zip   { width: 70px; }

form label.field-occupation   { width:150px; clear:left; }
form label.field-bday   { width:150px; }
...

HTML

...
<form>
  <fieldset>
    <legend>Basic Information</legend>
    <label class="field-title">
        Title &#42;<select name="EmployeeName.Title">
            <option value="Mr.">Mr.</option>
            <option value="Mrs.">Mrs.</option>
            <option value="Ms.">Ms.</option>
        </select>
    </label>
    <label class="field-first">
        First Name &#42;<input name='first' /></label>
    <label class="field-last">
        Last Name &#42;<input name='last' /></label>
    <label class="field-street">
        Street &#42;<input name='street' /></label>
    <label class="field-city">
        City &#42;<input name='city' /></label>
    <label class="field-state">
        State &#42;<select name='state' >
        <option>test</option></select></label>
    <label class="field-zip">
    Zip &#42;<input name='zip' /></label> 
    <label class="field-occupation">
    Occupation &#42;<input name='occupation' /></label>
    <label class="field-bday">
        Birth Day &#42;<input name='bday' /></label>
  </fieldset>
</form>
...

Doctype

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
A: 
form label { float: left; margin: 0px 10px 0px 0px;display:inline}

might work as display:inline tends to make ie behave itself better with floats & clears, but is ignored by good browsers when the element is floated.

wheresrhys
Works for IE 8. IE7 is still retarded. :( thoughts?
TheDeeno
Was a long shot. I reckon Emily's answer is the way forward.
wheresrhys
+1  A: 

I don't think you can without modifying the source. IE6/7 uses different float logic than the other browsers and there is not any way to tell them "don't float this all the way to the top".

This is why most forms use some sort of wrapper to clear the rows. I use divs

<div class="row">
    <label class="field-title">
        Title &#42;<select name="EmployeeName.Title">
            <option value="Mr.">Mr.</option>
            <option value="Mrs.">Mrs.</option>
            <option value="Ms.">Ms.</option>
        </select>
    </label>
</div>
<div class="row">
    <label class="field-first">
        First Name &#42;<input name='first' /></label>
    <label class="field-last">
        Last Name &#42;<input name='last' /></label>
</div>

.row {clear:both;}
Emily
This works, I'd really like to see if there is a css only way. This is currently the only working solution. Surprised it got down voted.
TheDeeno
A slightly better way of doing it might be to wrap the whole thing in <ol> and wrap the label/input pairs in <li> elements. Then use CSS to remove the numbering, and reset padding and margin on the list.
wheresrhys
I decided to suck it up and go with this work around. Its certainly the most stable. @wheresrhys I think the div with class "row" is more semantic than an arbitrary list item. If I was listing 1 field per item it'd might make more sense.
TheDeeno
A: 

As Emily said, it's not going to work with floats... But then of course, you can just not use floats where appropriate.

Change the following statements from your original CSS, turning them from floats into (inline) blocks:

form label.field-title  { width: 50px; float: none; display: block; }
form label.field-last   { width: 150px; float: none; display: inline-block; }
form label.field-street { width: 310px; float: none; display: block; }

form label.field-zip   { width: 70px; float: none; display: inline-block; }

This will continue to work in other (recent) browsers too.

How does it work?

The problem with IE7's floats is that they can "bubble up" through other floats. E.g. the reason field-last ends up next to field-title is because it doesn't clear its left unlike field-first. But instead of staying next to the field-first it just moves up through it next to field-title.

The easiest way to fix that is simply to make field-title a block. That prevents it from any following floats appearing next to it. The same goes for field-street. You don't want anything to appear next to it, so you can just turn it into a block.

That doesn't work with field-last, however, because in standards-compliant browsers, the block essentially contains the preceding float. But since that already takes up its full width, there's no room left next to it. Making it an inline-block instead does let it keep its block properties while putting it next to the float, instead of encompassing it.

The same thing goes for the field-zip, with only one difference. field-last is already followed by a block, so it doesn't have to worry about anything floating to its right. field-zip, though, is followed by a float, so that needs to clear its left to prevent it from coming up next to the Zip code.

mercator
Does this not work?
mercator
if you downvote, please leave a comment
marcgg
I didn't vote down. Testing this shortly.
TheDeeno
This might not work right. I'm trying to understand it. Can you make it work for the updated form (in question) so I can better see the pattern?
TheDeeno
note i had to fix a typo in the css i posted.
TheDeeno
I noticed the typo... I've updated the fix. I'm still working on explaining how it actually works.
mercator
+1  A: 

EDIT: I added a width to the fieldset and a right margin to the title label:

form fieldset { width:320px; }

form label.field-title { width: 50px; margin: 0 250px 0 0; clear: left; }

This makes the title <label> take up most of the fieldset width, forcing the other elements down into place.

You can see a demo of this by going here with IE7: http://demo.raleighbuckner.com/so/1369556/

EDIT 2: The best solution to this is to do as Emily (and wheresrhys in a comment to Emily's answer) suggests and put each line of your form fields in a wrapper. Personally, I like to use unordered lists (like wheresrhys). An example of this can be seen in this demo: http://demo.raleighbuckner.com/so/1369556/default2.htm

81bronco
This floats everything left in all browsers. I want the form to appear as it currently does for FF or Chrome and either mirror that behavior, or degrade it nicely for IE7.
TheDeeno
ahh... gotcha. let me see what I can come up with.
81bronco
Fantastic! Drop the old answer so others don't get confused. I ended up only needing to use the first part of your answer. Basically you're just avoiding the need to clear by making each field take up so much space that the following block is forced to the next line. Right?
TheDeeno
Yes. It's a bit of a hack to make the items take up the available space. I would recommend the unordered list or div method to be the most stable.
81bronco