Trinity: Separating Structure, Presentation, and Behaviour

This is not intended to be a full treatise on CSS or client-side scripting. It is intended as a brief cross-reference for some of the other pages on this site. For more information on the separation of structure, presentation, and behaviour in web design, there is a discussion by Jeffrey Zeldman in Designing With Web Standards (New Riders) and by Peter-Paul Koch.

The way we were

The web was originally developed as a utilitarian approach to information exchange between academics. It was devoid of all but the most basic of presentational characteristics.

And then came designers. And they looked upon the web and saw it was not good. Or, rather, they saw it was not pretty. It didn't engage the visitor. So structural and presentational tags, and JavaScript calls within those tags, were added to the HTML markup.

But this approach brought problems. Firstly, ‘code bloat’ increases page size and thus slows download speed, particularly on slower connections. Secondly, it's very difficult to change the look or behaviour of the document, as it involves extensive editing. Thirdly, it's difficult to repurpose the page content for use with other devices or technologies. Finally, the additional code has no intrinsic meaning.

Structure

Traditionally, web pages were given structure using tables. For example, a column layout could be created using a table with one row and as many columns as was needed. The problem with this approach is not only the relatively large amount of code required to simply achieve the page structure, but also that this code is semantically meaningless. Tables are meant to display tabulated data, not define structure. Often tables were nested to achieve higher degrees of structure. The most complex pages could have many levels of nested tables. For example, a simple two-column structure might look like this:

<table> <tr> <td> Left column content </td> <td> Right column content </td> </tr> </table>

But if the right-hand column required an upper and lower panel, then the code was often expanded to include a second table nested within the first:

<table> <tr> <td> Left column content </td> <td> <!-- right column content is a table --> <table> <tr> <td> Upper panel conent </td> </tr> <tr> <td> Lower panel content </td> </tr> </table> <!-- end --> </td> </tr> </table>

This example is, of course, simplified to show the structure. After presentational code is added to set cell padding and spacing, table borders, text and background colours etc. the final markup looks a lot more complicated! The structural code could be simplified somewhat by using the colspan and rowspan attributes of table cells in order to reduce the deep nesting of tables. But this requires a lot of forethought and isn't easy to adapt to later design changes. Consequently, although not the most elegant solution, table nesting prevailed.

If, however, use is made of the div tag, which was created for the purpose of structural markup, then the structural code can be reduced substantially. The resulting code is not only leaner, being quicker to download and easier to read for direct editing, but it's also easier to style and more flexible to design changes.

<div> Left column content </div> <div> <div> Upper panel content </div> <div> Lower panel content </div> </div>

The structural markup itself doesn't inherently confer a presentational structure to the page, unlike the case with tables. Presentational structure is achieved with the appropriate use of CSS. This allows for far more flexible layouts than tabulated structure. And no further code—with the exception of id and possibly class attributes—is needed within the structural code to implement non-structural presentation, as all presentation is applied through CSS.

I've created the same three panel layout above using both tables and semantic structural elements (it's basic rather than beautiful—think ‘demonstration purposes’). The file sizes are small—6,875 and 6,269 bytes respectively—but, then again, the pages are simple. The latter is reduced to 4,636 bytes if the embedded stylesheet and JavaScript are removed to linked libraries, which could then be shared across all the pages of the same site. Obviously the file sizes, and consequently the savings to be made by using semantic markup, will increase with more complex designs.

Actually, this approach to structure isn't a panacea by any means. Browser support for the presentation of more complex structures is not as uniform as is the case for table-based structures. This led to a plethora of CSS hacks aimed at specific browsers to force them into conforming with a specific design goal. Personally, I loathe hacks and would prefer to go for a simpler design or the 80:20 rule, while using conditional comments to address any shortcomings of the ‘world's favourite browser’. The situation is improving as the market moves away from Internet Explorer versions 5 and 6 towards browsers that offer better standards compliance. But it's still not straighforward to create everything that could be achieved with the older methods.

Presentation

Beyond structural presentation (i.e. the placement of objects on the page, as discussed earlier) designers want to set the look of page elements. Colours, typeface, images were all styled to suit the design goal for a site. While overall page styling was controlled with attributes added to page elements (sometimes at the expense of validation), typography was controlled with a handful of dedicated phrase elements and the FONT tag with its FACE, COLOR, and SIZE attributes:

<P><FONT FACE="Arial" SIZE="2"><B>Bold</B> or <FONT COLOR="#FF0000">red</FONT></FONT></P>

Although this would commonly be found in a more bloated format:

<P><FONT FACE="Arial"><FONT SIZE="2"><B>Bold</B> or <FONT COLOR="#FF0000">red</FONT></FONT></FONT></P>

Presentational code bloat was addressed by the introduction of styles to web design, through cascading style sheets (CSS). Styles can be assigned to document objects, and the styling information itself removed from the markup. This makes for a very flexible approach to presentation.

Styles can be applied in one of three ways. In order of decreasing complexity and increasing flexibility, these are:

  1. Inline: the style is added to the element tag to which it applies
  2. Embedded style sheet: styles are collected together in the HEAD section of the page
  3. External style sheet: a separate document (or documents) which are referred to through a LINK tag.

The precedence of a style in determining the presentation of an element in competition with other styles is dictated by two factors: its proximity to the element (i.e. inline styles override embedded style sheets which, in turn, override external style sheets), and the cascade.

But why are inline styles more complex and external style sheets more flexible?

Maintenance of inline styles requires that each instance of a style has to be found and edited. With search/replace in HTML editing applications, this is often not too onerous. But it also adds code bloat. Take, for instance, the case where a page holds five images, which are required to lie within and on the right-hand side of a text block, with a border, and the text no closer than 10px. Using inline styles, each IMG would look like this:

<img ... style="float: right; margin-left: 10px; margin-bottom: 10px; border: solid 5px #000">

Whereas if this styling code is removed to an embedded or linked style sheet, the style not only becomes easier to manage, the page size is reduced. The real advantage to manageability is when styles are removed to a linked external style sheet. Site-wide changes can be made instantaneously.

Behaviour

In this instance ‘behaviour’ refers to the response of a site to user interaction via JavaScript.

Two elements determine the behaviour of a page to user input: a function or method, which actually performs the desired action, and a call to that function or method.

Scripts are generally written in the HEAD section of the page or in an external ‘script library’. The function call can be placed in the tag of the element to which it will be applied, or the script can be invoked through another trigger (e.g. during the loading of the document in the browser) while targeting elements with, in the case of the W3C DOM, document methods such as getElementById and getElementsByTagName.

In a similar vein to style application, inline function calls are eschewed. An inline call would look something like this:

<img ... onclick="window.close()">

But this adds extra code to the HTML markup, and again makes maintenance more difficult. A better approach is to put the function calls in the script and initiate and target the script through other mechanisms. For example:

<script type="text/javascript"> <!-- window.onload = myFunction; function myFunction() { if (document.getElementById) { ... do something with an element ... } } //--> </script>

In this manner, the only code added to the element's tag is an id attribute. Any number of scripts can be made to work on the same element through its id.