That said, here’s a brief re-cap of some of the fundamentals of HTML document flow that’s easy to look over when you’re working in GWT land:
Document Flow: Block, Inline, & Inline-Block
Every html element contributes to the flow of content on the page. Most of these elements are classified as either block level elements or inline elements, which affects how they fit into the flow of content. Elements may have their natural display mode changed via CSS by setting the display attribute.
Block elements span the entire width of their parent element and cause the next element to start on a new line. In effect, they stack on top of each other like blocks. Block level elements accept the full range of css margin and padding styling.
Examples include: <div>, <p>, <form>, <blockquote>, <h1>, <h2>, and <ul>.
Inline elements, on the other hand, fit into the regular flow of text on the page and will automatically wrap when they reach the end of a line. Think of them as individual words or glyphs. Some special notes when dealing with inline elements:
- No width or height can be set
- While padding and margins can be set, only the horizontal values will affect content
- Never put a block level element inside of a inline level element
Examples include: <span>, <a>, <em>, <strong>, <input>, <button>, <image>
Inline Block – The Hybrid
Inline-block elements are a hybrid of block and inline block elements. They get the benefit of fitting into the flow of text like inline-elements, but they still support width, height, padding, and margin. Lets say you were to make a custom button in GWT with your own styling: you would probably end up using an inline-block display mode so you could get all your dimensions the way you want.
Inline-block is only recently cross-browser compatible – and you may run into a few quirks when working with IE6/7 (every other browser should work fine). My golden rule for working with it that tends to get rid of 99% of cross browser problems: only ever set display:inline-block on elements that are naturally inline elements.
Fitting them all together
Where do GWT widgets fit in?
Each GWT widget is implemented using an underlying native HTML element that will affect the document flow. When you use a widget, its important to realize what element you’re using behind the scenes, otherwise your your layout starts to become very haphazard. For reference, I’ve created a short table of some of the more common widgets.
Generally, most panel widgets are divs (blocks) and inputs, buttons, links, etc. map to their corresponding span elements as you would expect.
The exception to this rule is the HorizontalPanel and VerticalPanel. These widgets use table elements behind the scenes, and I strongly recommend you never use them for layout purposes.
Common Document Flow Mistakes in GWT
- Don’t set width 100% of block level elements. Block level elements naturally expand to fill their parent element horizontally – making the width 100% redundant. Even worse – width 100% is additive with padding and margin which can cause your div to expand outside of its parent all together.(The only exception to this rule would be if you are trying to clear floats using the overflow:auto technique. Still be on the lookout for margin and padding issues though)
- Don’t put a width, height, or vertical padding/margin on inline elements – they have no affect. If you need them – use inline-block elements. Another common technique to force vertical size is to apply a css line-height to the span.
- Never put display:inline-block on div’s or natural block elements. You’ll run into problems with IE6 and IE7.
- Never use tables for document layout purposes. This means that HorizontalPanel and VerticalPanel are strictly off limits.
- Never put a block level element inside a inline or inline-block level element.
- Clear your floats, otherwise you’ll run into problems with the content overlapping the document down stream. Two common techniques are to put a clearing block (<div style=”clear:both”/>) or using the overflow:auto technique.