Making the web work for you

creating optional columns in website layouts


Tuesday, April 27th, 2010

Our CMS has a number of features which allow its users to create panels (or columns), change templates, etc.

A template is basically a variant of a design. We usually have a number of different templates for each design, so the administrator can have some pages that have columns on the left or right, pages with no columns, and pages with columns on both sides.

Here are some example column layouts. I’ve used tables for these examples. The demos will show how to create these layouts using CSS.

content
left column content
content right column
left column content right column

Creating multiple templates for every design can be tiresome; especially if only one or two ever get actually used in the site itself – we really want to just have a single template which can be styled differently depending on whether the HTML has the columns in it or not.

I’ve written up a small demo. In it, there are four pages, one for each layout described above. A thing to note is that the demo uses the same IDs for each layout, and they’re all reading from the same style-sheet.

If you examine the HTML, you’ll note that the columns are divs, and the only difference between the various demos is that the columns are added to the HTML. You don’t need to change any IDs or classes to trigger the layout change – just add the HTML.

Example: here’s the HTML for the first one, with no columns:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<style>@import "style.css";</style>
	</head>
	<body>
		<div id="container">
			<div id="centre-column">content of page.</div>
			<br />
		</div>
	</body>
</html>

And here’s the final one, with columns on the left and right:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<style>@import "style.css";</style>
	</head>
	<body>
		<div id="container">
			<div id="right-column">right column.</div>
			<div id="left-column">left column.</div>
			<div id="centre-column">content of page.</div>
			<br />
		</div>
	</body>
</html>

Note that the only difference is that the second one has the extra columns added. And yet the #centre-column div knew to re-shape itself to allow room for the columns.

So, how does it work?

In CSS, there is a combinator called the “adjacent combinator”, +. This combinator means “the element next to what we’ve already selected”.

For example, let’s say we have this HTML:

<div class="panel-right">right panel</div>
<div id="content">content</div>

If we want #content to have a margin-right of 150px, we could use this:

#content{
  margin-right:150px;
}

But that will apply whether the .panel-right HTML exists or not.

If we want the #content to normally have a margin of 10px, and 150px only if .panel-right is there, we can use this:

#content{
  margin:10px;
}
.panel-right + #content{
  margin-right:150px;
}

What that means, is "the #content element which is next to .panel-right should have a margin-right of 150px".

In the demo, we expand on that to have different rules allowing various combinations of columns to exist. I've used IDs in the demo, but you can replace those with classes, or whatever other way you want to select elements.

One thing to note is IE7 and IE8 - this works in both of those, but you need to trigger standards-mode in them to get them to comply.

The way you do this is to add a DOCTYPE declaration at the top of the HTML. Example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

This tells the browser to use standard CSS and not to use it's own made-up version of it ;-) . Your HTML doesn't have to be absolutely correct - just tell the browser that it is.

One Response to “creating optional columns in website layouts”

  1. cswake Says:

    Nice write-up and illustrated code. Thank you!

Leave a Reply