Tableless Float-free Layouts Part 1:
The Deceptively Simple Form

Summary

Creating a pretty cross browser form requires just one basic CSS rule:
Use it always. (demo)
	span,legend{display:-moz-inline-box; display:inline-block}


Understanding the display property:

The CSS 'Display' property was introduced way back in CSS v1 as a way of setting the layout ["display"] of the element.
But while the W3C has defined almost 20 valid values and Mozilla has added another dozen, only five have common support:
  1. "block": Give an entire line to the element.
    No elements will be to its left or right (Except those above the layout).
    If width is not set, it will stretch horizontally to fill the parent.
  2. "list-item": same as "block", but with an added number or bullet to the left of the element.  Used in this list.
  3. "inline-block": Insert the element into the page layout as if it were a word of text.
    It follows immediately after the item before it and flows to the next line if there is not enough space for the whole word/element.
  4. "inline": The same as inline-block, but with the element's width and height properties disabled. In effect the same as a forced style="width:auto; height:auto".
  5. "none" : Don't display the element at all.
    Hides the element.
Some elements such as the <span>, <a>, <b> & <i>, have the display set to inline.
Being such, they are so unobtrusive you wouldn't know that I put 3 into this sentance alone. (Check with Firebug ;))

Others elements, such as the div, pre, and p, are block level. They make their presence

known!

I know what you want to ask: Why in the world would anyone use inline instead of inline-block?!
What possible benefit could be gained by disabling the width & height?! [Especially considering that width and height are never inherited in CSS].


Good question. No, more than that. Great question!!

But the fact is that the inline value exists, and the span, anchor, legend, and many other elements are set to "inline" by default.
In fact, they are known as "inline elements".

Now for the good news.
You can fix this.
This should be part of your own reset.css, used on every page you write:
	span,a,legend{ display:inline-block }
All done!
You can now layout your forms with spans and/or legends, and they will display exactly the way you want them to. Check it out (any browser will do):

With fixed widths:


Name:
Password:

<style type="text/css">
	span{display:inline-block} 
	#myForm span,input{width:125px;}
</style>
<form id="myForm">
	<span>Name:</span><input><br>
	<span>Password:</span><input type="password">
</form> 

With fluid widths:


Name:
Password:

<style type="text/css">
	span{display:inline-block} 
	#myForm span,input{width:49%;}
</style>
<form id="myForm">
	<span>Name:</span><input><br>
	<span>Password:</span><input type="password">
</form> 


Now, I know what you are all thinking: That was too easy.

Here's the catch:
  • The fluid layout I gave cheated a little (width:49% instead of 50%) to compensate for the input's border. The "real" solution for borders is in part two of this tutorial.
  • Firefox 2 doesn't support inline-block. Boom!
However, Firefox is nice to us:
They have a matching attribute that they call -moz-inline-box, and as long as you drop it in before the inline-block, it is picked up by FF2, and ignored by all other browsers.

So the new solution is slightly longer, but works the same, including FF2:
span,a,legend{ display:-moz-inline-box; display:inline-block }
[ It's actually a wee bit more complicated, as -moz-inline-box !== inline-block. It does not correctly wrap content that is placed directly into it.
If the tiny number of FF2 users are a concern, make sure you test first that all is alright.
In the odd circumstance that it looks wrong, switch to -moz-inline-stack, or -moz-inline-block, as these complement each other. Or wait till part 2, where we offer another solution.]

Whew. OK. Now for Internet Explorer

Internet Explorer could not have gotten this right... where are all of the IE specific hacks?

They are here, but none are directly related related to the above rules: (ie. you don't really need any!)
  • Problem: In IE6 & 7 inline-block can not be applied to block level elements such as the div or the p.
  • The hack: Add an IE only display:inline in a separate command. The first time sets the element to haslayout, the second sets the display property. So we get:
       div{ display:-moz-inline-box; display:inline-block }
       div{_display:inline}
    
       /* or for standards compliance */	
       <style type="text/css">
     div,p{ display:-moz-inline-box; display:inline-block}</style>
    <!--[if lt IE 8]><style>div{display:inline}</style><![endif]-->
    
    Weird, huh? No. Just IE.
    But be forewarned that setting haslayout so globally can have unintended consequences in IE. If you insist on using divs to layout the form, use more specific CSS targeting.

  • Problem: Sometimes you want to set a minimum and maximum width height while using a percentage based width.
  • This is a bit of a notorious problem, as M$ claimed to have fixed it in IE7, while in truth they just made it far worse.
    It part two we will discuss the various workarounds.


  • Problem: Using positioned elements within anchors and other inline elements sometimes looks odd.
  • This has nothing to do with inline-block, and everything to do with IE being buggy. It applies even if you don't change the display type. If you plan on using positioning within inline elements, try to stick the span as much as possible. They got the span almost 100% perfectly right.

After the commercial break...

  1. If you add borders, padding, or margins, you may find that fluid layouts are screwed.
    This is not the fault of inline-block, but does get in the way of its use.
    The solution for this is in part two.
  2. Mixing fixed widths with percentage widths is known as the holy grail of layouts.
    For that, please hold out till part III



blog comments powered by Disqus
Data Recovery Software