Altering the Relative Column Widths in Plone 4

The new default ‘Sunburst’ theme in Plone 4 uses the Deco grid layout system. Generally speaking, I like it.

One part that got to be a hindrance for me recently was the column widths. I just added a bunch of largish tabular listing views to an application I’m working on, and I need more real estate in the content well. Now, it’s a grid-based layout, so you’d think it would be easy to fix. In hindsight it’s pretty simple, but it took me a couple of hours to figure it all out.

First, you need to understand the grid approach. That’s a bit much to go into here, but it will help (look at the Deco site and specifically the css file).

Now, forget it.

Plone uses the convenience classes specified in deco.css (in the Sunburst theme, it’s slightly modified and called columns.css), dynamically assigning a width and position to the content well (aka #portal-column-content) depending on the available portlets. These classes specify positions and widths as multiples of columns within the grid. They have names like position-3:4 and width:1:2 (in the default 16-column grid these correspond to position 3/4 or grid column 12 and 1/2 of the grid width, or the width of 8 columns, respectively).

This means that the width of the grid doesn’t explicitly dictate the width of the columns. Technically, the widths are set explicitly by those convenience classes. This means we need to override those classes to change the column widths. This makes it a lot easier, but it obfuscates the real CSS rules that need to change.

Here are the classes used and when they’re in play (see the souce code for specifics):

  • No columns: .width-full, .position-0
  • 1 column: .width-3:4, .position-1:4
  • 2 columns: .width-1:2, .position-1:4

The portal columns (#portal-column-one and #portal-column-two) are always marked with .width:1:4. The left column (#portal-column-one) is always marked with .poistion-0. The right column (#portal-column-two) is always marked with .position-3:4.

What this translates to is a 2:1 ratio for the content vs. the portlet columns (25%-50%-25%).

If you look at columns.css, you’ll note the actual percentages drift a bit from those amounts. This is due to spacing between the grid columns (1.125% on each side).

Now for the example. I set up a policy product that registered a skins folder containing a file called shrunken_columns.css. I registered the CSS in the profile via portal_css.xml. You could also do the same through the web by adding shrunken_columns.css to the portal_skins/custom folder and registering the CSS in portal_css, just make sure that it’s registered somewhere after columns.css.

I needed to increase the amount of content space, so I picked a somewhat arbitrary ratio of 15%-70%-15%. I initially went for 16.5%-67%-16.5% but it was still a bit large and the math got weirder. Just remember if you’re doing this yourself to start with 3 values that add up to 100%.

So, my initial CSS looked like this (these are the only classes you need to mess with!)

div.width-1\3a 2 { width: 70%; } /* .width-1:2 */
div.width-1\3a 4 { width: 15%; } /* .width-1:4 */
div.width-3\3a 4 { width: 85%; } /* .width-3:4 */
div.position-1\3a 4 {margin-left: -85%;} /* .position-1:4 */
div.position-3\3a 4 {margin-left: -15%;} /* .position-3:4 */

Note the somewhat odd notation in the class definition. You must retain this format when you write your class definitions or it won’t work. This is explained briefly on the Deco site:

What’s with the \3a notation in the definitions for the width-1:2 etc. classes?

It’s a workaround notation since Internet Explorer 6 (and 7, possibly) doesn’t support the plain backslash escape for class names with colon in them. You can of course rename this if you think it’s ugly. We think it’s easier to think of three quarters as width-3:4 instead of width-3_4 or width-3-4.

I also noticed that Firefox 3.6, and the W3C CSS validator, don’t care for the colons either. :)

So this works, but it’s off a little bit since we ignored the allowance for vertical spacing. This can be handled with some math (and guidance from columns.css):

  • Each width needs to be reduced by 2.25
  • Each position needs to be increased by 1.25

This gives us the following:

div.width-1\3a 2 { width: 67.75%; } /* .width-1:2 */
div.width-1\3a 4 { width: 12.75%; } /* .width-1:4 */
div.width-3\3a 4 { width: 82.75%; } /* .width-3:4 */
div.position-1\3a 4 {margin-left: -83.875%;} /* .position-1:4 */
div.position-3\3a 4 {margin-left: -13.875%;} /* .position-3:4 */

This works quite swimmingly. I haven’t put it into production yet, so time will tell if it holds up, but I think this is the best way to handle an issue like this without just building my own theme. Critiques, other approaches, etc are welcome.

One note: I haven’t tested the modified CSS in an RTL language. From what I can tell from the code I should be OK, but YMMV. If you try this out and use an RTL language and have trouble, please leave a comment and let me know.

This entry was posted in plone, theme. Bookmark the permalink.

3 Responses to Altering the Relative Column Widths in Plone 4

  1. Torkel says:

    There is also a helper view registered in the sunburs theme. This view determines the width of the content column based on the portlets shown in the current context. By overriding this view you can alter the width of the columns. I dont think overriding the css classes is a wise solution, it can make third party product look akward.

    • jjmojojjmojo says:

      Which view would that be, exactly? Are you’re talking about this one: It’s the only one in the whole product, as far as I can tell from the source, unless the view you’re talking about is registered elsewhere?

      If that is indeed the view you’re talking about, it doesn’t assign widths to the columns, it assigns classes (I mention this in my post). Did I miss something?

      I’ve been thinking about the other point you raise and I’m having trouble seeing a situation where it matters, can you help me out? Specifically, which 3rd party products (or even, what kinds of 3rd party products would) rely on a specific portlet width?

      • Torkel Lyng says:

        That is the view I’m talking about. Modifying that and the is the usual procedure I take to alter the column widths (I often vary between 1/4 and 1/3 columns). On third party products I’m very unsure, perhaps there is no third party product that utilize deco at the time beeing.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s