Saturday, May 7, 2005

Grid Layout or Flow Layout?

WARNING: This blog entry was imported from my old blog on (which used different blogging software), so formatting and links may not be correct.

You have probably noticed that when you create a new page or project
in Creator, the page has a grid on it - and when you drag components
on it, they get positioned precisely where you drop them. This is
called "grid layout". Behind the scenes, we use

CSS 2 absolute positioning
to ensure that the component ends up
at the exact same position in your browser.

property sheet image

In addition to Grid Layout, you can change your page layout to
something called Flow Layout as well. Why would you use one over the

Grid Layout offers two main advantages:

  • It's easy.

  • It's fast.

If you want to create an input form, you can bang one out in no
time flat - drag components directly to where you want them, and size
them appropriately. Components automatically snap to the designtime grid,
which makes it easier to create a balanced looking page, but you can
do finer adjustments by pressing the shift key while dragging or resizing
to get the pixel coordinates you want.

However, Grid Layout does have some serious disadvantages:

  • Your pages do not resize well. For example, if you want your
    components to stretch when the user resizes the browser, you cannot
    do that with Grid Layout. (This is almost true... we'll get back to

  • Your pages will not adapt to differing font sizes in different
    browsers, or even user-overrides of font sizes. Many
    browsers offer a "zoom" functionality - I use it myself when I visit
    pages where the fonts are too small to be read comfortably.
    If you have designed a page where you have a label that is positioned
    exactly fourty pixels to the left of a text field, that will not
    work well if the page is zoomed to a much larger size since now
    the textfield will crop the label.

  • You don't get baseline alignment for components you intended to
    be on the same line. For example, you typically want a textfield
    to be aligned with the baseline of its label (such that
    the bottom of the textfield is aligned with the bottom of letters
    like "a" and "x", not letters like "j", "g" and "y".)

So should you just switch to Flow Layout for your page designs?

That's not a slamdunk either. Creating pages with flow layout is a lot
more tedious. You will basically be creating layouts the way pages were
done in the Bad Old Days - using layout tables. The closest thing you
can get to a layout table with the standard JSF components is the
Grid Panel component. The main disadvantage of the Grid Panel
however is that it doesn't offer cell merging with colspan and rowspan,
so you'll need to nest grid panels instead.

The good news is that you can get a lot of mileage with a hybrid approach!
The idea is that you can create the -rough- layout of your page using
grid layout to drop your components - a page fragment as a header,
a page fragment on the left as a navigation menu, and then a grid panel
or two or three in different areas, along with some text label components,
to finish your layout. You then drop your form components inside the

layout components (like grid panel) to finish your page. The reason this
is better, is that inside these layout components, the positioning
is using flow mode. In the screenshot on the right, the label, textfield and error
message in each row inside the grid panel will be laid out in flow
mode inside the grid panel, meaning that if the label takes up more room,
the adjoining textfield (and indeed the whole layout column) will move
to the right to make enough room to fully display it. Try it - in Mozilla/Firefox,
press Ctrl-shift-plus to zoom in on your page. Likewise, notice
how the Data Table below it has been put inside a Grid Panel, along with
the summary label below it. If we didn't do this, and simply placed the
label below the data table using absolute positioning, then when the
application is run, it's possible (and in fact, likely) that more rows will show in the data table,
and the table will run on top of the label. With the label inside
a grid panel, it will move down to always be right below the table.

I mentioned earlier that it isn't possible to have your grid layout
components stretch when the browser is resized. That's not true; you
can use percentages on your width and height settings for the components.
This is tricky however and doesn't work very well. Let's say
you drop a component at (100,100), and set its width to "100%". Now
the width of the component will stretch to the full width of the browser.
The problem is that this does NOT consider the position of the component.
So if the browser window is 800 pixels wide, the component will be
800 pixels wide, but since it's positioned at (100,100), the right
hand side corner will be at (900,100) and you will have a horizontal
scrollbar - not what you intended I'm sure.
The easiest way to "fix" this is to simply make the percentage
less than 100%, say 80% (or gradually less the further your component
is positioned to the right) but it should be clear that this is a hack.
You can counteract some of these effects using negative margins and such
but I don't recommend it.

The main point I wanted to get across in this blog is that even though
the page layout property makes "Grid Layout" or "Flow Layout" an
either/or-decision, the reality is more complex; every component can
be positioned in flow mode or absolute positioning mode. What determines
this is the style property on the component.


  1. Thanks! This is the best commentary on how to do page layout in Creator I've found.

  2. Excuse me! When I drop the form componet into grid panel, the JSC can't accept this action.
    Can you give me some advise?!
    Thank you!!

  3. Turns out the Form component's metadata has specified that it can only be the child of a Body component. That's wrong, and we have fixed that now in the dev builds, but in Creator 2 EA, your workaround is to drop it somewhere else, then go to the JSP source tab, cut & paste the form component and paste it in under the grid panel element.