How Gpanels Work - the Secret Sauce

When I first built Gpanels I ran into the usual layout problems when using percentages—IE rounding up, Operas inane percentage rounding behavior and a bunch of other pita issues.

I decided there must be a better way of achieving the layout I was looking for, and not using grids, because my base theme is not grids based.

Either I had to change my base theme to have left and right padding on the main layout containers (didn't really want to do that as it created more havoc) or I dream up a better way of laying out horizontal panels, because a key design requirement was to have no margin/padding of the first and last panels (so they sit hard against the left and right edges of their containing box), indeed, I did not want to use any margin or padding at all to either create the gutters between each panel or take them away.

So I came up with the secret sauce, and I'm going to explain how this revolutionized the way I layout Gpanels.

First though a caveat. The 2 and 4 column Gpanels use opposing floats, so they are not of interest, it was very easy to achieve their layout with opposing floats and I just decided to leave them be. What was harder are the 3, 5 and 6 column Gpanels, and thats where our secret begins.

Mix one part float, and spice with position:relative

First lets look at the CSS for 3 column 3x33 Gpanel.

/* Core CSS that applies to all Gpanels. \*/
.gpanel {margin-bottom:.75em;clear:both;}
.gpanel .region {display:inline;position:relative;}
/* .three-col-3x33 layout. */
.three-col-3x33 .region {float:left;width:32.66%;}
.three-col-3x33 .col-2 {right:-1%;}
.three-col-3x33 .col-3 {right:-2%;}

See the HTML below, both the .region and the .col-x classes are on the same DIV, so all inherit position:relative.

So as you can see, each panel (.region) if floating left and has a width set on it. That width is 100% minus the gutters (1% each is out aim), which equals 98%, we then divide by the number of panels (3) and we get our panel width—32.66%.

Now we could use margin-left:1% to achieve the gutters, but uh oh, IE rounding is going to bork the layout so thats not an option. The secret sauce is the cunning use of position: relative to shift each panel over to right 1% more than the previous panel.

The whole equation looks like this:

* 100% width minus number of gutters = n
* n divided by the number of panels = panel width
* position relative right -x%
* for each panel increment x by 1% (starting from the second panel)

So its all very simple and it works in all browsers and allows you to build unlimited number of columns without worrying about IE's rounding up shenanigans.

Heres the HTML (and PHP to boot) for the above layout.

<!--//  Three column 3x33 Gpanel   //-->
<?php if ($three_col_3x33_first or $three_col_3x33_second or $three_col_3x33_third): ?>
  <div class="three-col-3x33 gpanel clear-block">
    <div class="section region col-1 first"><div class="inner">
      <?php if ($three_col_3x33_first): print $three_col_3x33_first; endif; ?>
    <div class="section region col-2"><div class="inner">
      <?php if ($three_col_3x33_second): print $three_col_3x33_second; endif; ?>
    <div class="section region col-3 last"><div class="inner">
      <?php if ($three_col_3x33_third): print $three_col_3x33_third; endif; ?>
<?php endif; ?>
<!--/end Gpanel-->

For those of new to Drupal the .clear-block class is Drupals version of .clear-fix.

Last updated 29th July, 2009 - 8:07pm

Authored by Jeff Burnz on