Wednesday, August 11, 2004

Structuring your pages: Part I

One of the precursors to any website redesign bent on using Web Standards is asking, then answering, the question: "how should I structure my page?" Structure, in the sense discussed here, is how content is represented in HTML code. This discussion does not include structuring anything outside the body tag, rather it will focus on the structure of a page's content and the page's content containers.

The structure of the code between the body tags is generally represented in code by two concepts: structural markup and content markup.

Structural markup can be thought of as the skeletal framework of any HTML code. It has no real meaning except to divide the page up into logical sections in which content markup can be added. I used the word divide on purpose. Since structural markup is meant to represent essentially meaningless, but organizational, divisions, it is customary to use a <div> tag. We will discuss the considerations of marking up every structural block below.

The second type of markup is content markup. Content markup are the semantic containers in which a page's content resides. As it turns out, most content falls into three categories of elements: headings, lists or paragraphs. These elements are usually represented in code with tags like: ul, ol, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, and p. Unlike the structural markup, these tags have real meaning and their use represents something both in code, to a machine, and to human looking at the code. As a note, just about anything can be content markup. In some sense, even the structural markups are a type of content markup, and there will inevitably be times when generic containers built from div tags would fall under this category.

In each case, there is a mental process and a set of decisions to be made during the process. Some are trivial; others are not. In this section, we will first look at structural markup. In a later post, we will examine content markup.

Structural

Structural markup seems to be the toughest concept for new developers to understand. In part, I blame this on the fact that never before have table-jockeys had to even consider this concept in the abstract. Rather they created a series of table cells and placed their content within the appropriate table cell. Nevertheless, those table cells are probably the primordial ooze from which to begin thinking about how a page is going to be structured.

A general case can be made that most webpages have at a very minimum a header, a content and a footer section. In tables, these might well be three table-rows and three table cells. Conceptually, this would put the header on top, the content in the middle and the footer on the bottom. Indeed, the table structure would also, in most cases, dump to the screen exactly like this. For example:

<table>
	<tr><td>Hi! This is my header</td></tr>
	<tr><td>This is where I'd put all my content!</td></tr>
	<tr><td>I'd probably have a copyright, and footer information down here.</td></tr>
</table>

As always, this type of table-think is dangerous. While in the simple case, this might work, it will nevertheless lock a developer into a particular design concept. What happens when you add navigation? Two navigations? What if you want to switch the order of the navigation and the content? In every case, you begin to complicate what started off as a simple, short table.

The tabular layout is also wasteful. Notice that to simply get the stacking effect we needed a wrapping table tag, three rows, and three cells. It would seem that at least three, if not four, of those elements are unnecessary.

Instead, let's think about what is really being said in when developers layed out that table. The mental process probably went like this:

  1. Hmmm... I need a page
  2. I know I want my logo and stuff at the top
  3. I have some copyright information that goes at the bottom
  4. And all my pages will have some content that will be different.
  5. I'll also want to have some navigation

As I noted above, this discussion is only dealing with the stuff between the body tags. As such, the creation of a body tag gives us the first step: "I need a page." In table-think, it would be the combination of <body> and <table> that would fulfill this first step. We'll see in a bit, that for the sake of "more containers" we may add another element here, but for now, let's not.

Deciphering the mental process

The second step, "I need stuff at the top", begins the more difficult work. "I need stuff at the top" isn't much help, until you translate the "need" into something more elaborate as "I need a special section [division] to add the important branding information at the top of the page." There are three components to this step: the elemental, the division, and the visual/logical placement.

What the mental process in the second step is telling us is that the developer already has is a concept about what he needs (a discussion of elemental markup), where it needs to go (a pseudo-CSS discussion), and that this is somehow distinct from other parts of the page (the structural discussion). In the instant gratification world, most table-thinkers skip right to the elemental and layout discussion. However, this skips perhaps the most important step: the first step in our structural plan.

The header

In the publishing world, this logical division is called masthead or in simple terms the "header". Aside from what the developer thinks is appropriate content for the "header", we need no further information to build our first structural element, we'll call it "header":

<div id="header">
<!-- I will put all the stuff for my header:
	logo, slogan, etc between these tags -->
</div>

There are a couple things happening in this small piece of code. First, the <div> tag becomes a container for anything that the developer feels belongs in the header. We need nothing more than these two itty-bitty tags (one open and one close). Second, we have identified the header using the id attribute.

Using ids vs. classes

Allow me to digress for a moment. A common question is raised about when to use an id and when to use a class. While there is no hard and fast rule because they can function the same way, I tend to think of ids as special cases of classes where I can guarantee the uniqueness. Since High-level structural elements are almost certainly unique and as such they are best described as a class. Since a page probably should not have more than one header, using an id makes some sense. In addition, we can logically directly address ids in both script and CSS with little concern that there will be more than one of them.

What are block level elements?

A <div> tag, by itself does nothing. It is a generic block level element. Block level elements, by default, are elements which force a line break on open and on close. Block level elements, by default, consume the entire available horizontal space. By default, they consume only as much vertical space as necessary. In addition, block level elements stack on top of each other. They can also contain other block level elements and other inline elements. In addition, they are supposed to apply padding, margins and borders according to the traditional box model. All of these are the default behaviors of a <div>. Nonetheless, these behaviors can be altered by CSS.

Knowing this, though, we can now think about where this container (note: I will use block, element and container synonymously) in code. Which leads us to another part of the ideas in the mental process: placement.

Conceptually, logically and perhaps visually the header belongs first. The first two are satisfied simply by placing the code first: ie. right below the <body> tag:

<body>
	<div id="header">
	<!-- I will put all the stuff for my header:
		logo, slogan, etc between these tags -->
	</div>
</body>

Also, knowing the default behavior of a block level elements, placing the header block first in code will also mean that it will display at the top of the page. Though there are a few things to note. First, the default behavior of the body is to have some margin and padding. If you expect your header to be flush against the viewport (the rendering part of the browser), then you need to turn of the margins and/or padding in the stylesheet: body { margin: 0; padding: 0; }. Second, no matter what you inside the header block, by default, everything subsequent to header will stack. If you start changing the default behavior, ie. using position: absolute; or float: left;, you may change how subsequent elements interact with this block. For example, floating blocks within the header, may cause the header to not contain those elements. All of this discussion are problems innate to CSS, not to the structure, though.

The stacking behavior, though, is the behavior most developers expect, and it is an important default behavior to remember. Knowing this alleviates the "how do I get my header and footer to be on top of and below my content, respectively" questions.

With this in mind, we are finished discussing the header, and will make understanding the footer and content blocks easier. Oops, I've given away parts of the subsequent mental process. You'll find that once you're familiar with structuring one part, each additional part becomes easier.

The third is a common requirement for a more or less static footer, "I have some copyright information that goes at the bottom". This can be translated as, "That legal mumbo-jumbo needs to be below my other stuff." Using the methodology from above we know a few things:

  1. We need a container
  2. This is probably unique and we can give it an id
  3. We don't need to worry about the content yet
  4. This is, for now, conceptually, logically, and visually last
  5. By default, blocks will stack, we don't need anything more

With this in mind, we can make our container. Almost universally, the bottom of a page is called a "footer". As such, we'll name it to match. Again, there are probably not two footers and thus we can use an id.

<div id="footer">
<!-- I will put all the stuff for my footer:
	copyright, contact info, etc -->
</div>

Since we know that the blocks will stack and that this is conceptually last, we can add the block to our code:

<body>
	<div id="header">
	<!-- I will put all the stuff for my header:
		logo, slogan, etc between these tags -->
	</div>
	<div id="footer">
	<!-- I will put all the stuff for my footer:
		copyright, contact info, etc -->
	</div>
</body>

If we were to fill in some dummy content, for header and footer, we would see that they're exactly how we had imagined them. The divs do not change much about the output. They do, however, in code, logically group the content within the containers. Since they're grouped using ids, we can manipulate individual elements' style in CSS using the following format: #header h1 { ... } and #footer p { } which will apply styling specifically for that container.

We can now add the content block.

The content block

The content block is no different than the header or the footer. The content block, however, is the block that usually contains all the "content" (imagine that) that a end user is looking for. In mental process three, we said, "And all my pages will have some content that will be different." Here there is no explicit reference to a container, but one can be inferred.

In theory, you don't need any containers for anything. You can develop a perfectly legitimate page without ever marking up the structure. However, when it comes for us to code or differentiate parts of content, if we do not have the containers, we fall back on classing every element on a page. For example, if we place a <h1> in our header and our content has an <h1> as well, if we didn't have the containers how could we differentiate the two? You could do <h1 class="header"> and <h1 class="content">, but that's ugly and inefficient. You'd very quickly realize that every element had to have a class.

So as we think about the content section, we can see that two things are possible. First, we could just simply allow the developer to add the new content between the header and footer sections, or, second, we can add another block.

Here in lies one of the more difficult decisions: to block or not to block. The decision is a both a design issue and a practical issue.

Practically speaking, adding more divs increases overhead, a little, and increases the code's complexity, a little. However, it also increases your specificity, provides more elements upon which to apply styles, and may ultimately improve readability and maintenance. On the other hand, embedding too many divs into your code can lead to the polar opposite.

As a compromise, I personally always try to wrap related content, at least one time. In this case, while our content could potentially go without any container doing so might potentially allow hundreds of content elements which should be related to not be. As such, we'll create a block called "content."

<div id="content">
<!-- This is where the content for
	a page will be entered -->
</div>

From our previous rules, we know that this block will be between header and footer.

<body>
	<div id="header">
	<!-- I will put all the stuff for my header:
		logo, slogan, etc between these tags -->
	</div>
	<div id="content">
	<!-- This is where the content for
		a page will be entered -->
	</div>
	<div id="footer">
	<!-- I will put all the stuff for my footer:
		copyright, contact info, etc -->
	</div>
</body>

With only three tags we have done much the same as the table whilst providing infinitely more specificity and flexibility. However, we haven't yet completed our fifth requirement. As we mentioned before adding navigation to the tabular layout meant knowing something more about the design and would further complicate the simple table. Using the structure we've created, and knowing nothing about the ultimate layout, we can add a container for navigation very quickly. So quickly in fact, that it doesn't get it's own section.

Though, before we add navigation, we need to consider one more thing. Our business rules say nothing about where the navigation should go relative to the content. That is, we know that navigation belongs between header and footer, but beyond that we're offered no additional help. Furthermore, we have not considered any design issues left/right/top/bottom in our structure, so we cannot look to this for guidance. What we do know is that search engines rank content by order in code. The nearer the top the better the content (top-down precedence), or at least so the theory goes. We also know our navigation is probably repetitive, but still necessary. However, it is the "content" on the page that is the most important. As such we probably want the navigation below content. We also know that our footer is last, that was another design requirement.

With that in mind, we can add navigation:

<body>
	<div id="header">
	<!-- I will put all the stuff for my header:
		logo, slogan, etc between these tags -->
	</div>
	<div id="content">
	<!-- This is where the content for
		a page will be entered -->
	</div>
	<div id="navigation">
	<!-- This is where my navigation links
		will be -->
	</div>
	<div id="footer">
	<!-- I will put all the stuff for my footer:
		copyright, contact info, etc -->
	</div>
</body>

In a typical tabular layout, with navigation on the left and content on the right, the navigation would probably be ahead of the content in code. In addition, a tabular layout requires us to move code around if we were to want to move navigation to the other side.

More structural elements?

Looking at our code above, it is conceivable to find several more logical groupings. The most obvious is a grouping around content and navigation. Why? Simple, header and footer have hard and fast rules about location: top and bottom, respectively. Everything else, in this case content and navigation, is between those two. There seems to be a relationship of "everything else" there. Whether or not this particular grouping is good or not might also affect how flexible a design could or could not be (ie. relatively positioning navigation, etc).

Another possible grouping would be a div containing all the blocks. This would be strictly a shortcut for some design features that reflected how all the containers were handled (ie. max width and horizontally centered blocks).

Conclusion

Structural markup is conceptually very simple. So simple, that once you've found a structure that you like, most subsequent designs will follow almost exactly the same structure. The key to figuring out an appropriate structure is figuring out your page's content needs and asking the sometimes difficult business questions.

0 Comments:

Post a Comment

<< Home