Chapter 9. Page Layout with Frames That Aren’t

Many of us don’t realize how much site layout decisions affect end users. These kinds of decisions are a little outside the scope of this book (they are truly design issues). However, there are some important questions regarding how the site is laid out from a coding standpoint, not from the designer’s point of view. By coding, I mean the design of elements that are used to define the application’s structure. These elements are the controls and widgets that go into an application built with XHTML, CSS, and JavaScript (and that you can enhance with Ajax).

Sites used to be structured with frames in the old days of web building, especially when the sites were doing more than just showing one page at a time. That changed out of necessity, as DHTML took hold and the limitations of frames became more evident.

Using Frames

Frames allow a developer to divide an application page into named sections that can still interact, but never overflow into one another. This has its advantages and disadvantages, as you can well imagine. On the one hand, it allows for easy layout from a development point of view. On the other hand, it is hard to create dynamic content that can interact anywhere on the page, because anything dynamic is constrained to its own frame.

If you decide to use frames, the XHTML 1.0 Frameset document type definition (DTD) is available, as is the HTML 4.01 Frameset DTD. Use whichever you like, but remember, the Web deals with XML a great deal, and that trend will not stop anytime soon. It would be better to not have to change so much of a site by at least following XML standards and using the XHTML 1.0 Frameset DTD.

Tip

The declaration tag for HTML 4.01 Framesets is:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/
TR/html4/frameset.dtd">

The declaration tag for XHTML 1.0 Framesets is:

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

It is important to use proper declarations in your application so that your browser stays in Standards mode when rendering pages.

The Frameset and Frame

You use the <frameset> element to define the page’s frameset—what a surprise! You use it to organize multiple rows and columns that may be nested within the page with a <frame> element. Within each frame is a separate document that will be loaded. You specify rows and columns for the page through the <frameset> element’s two attributes: rows and cols. Table 9-1 shows the attributes available for a <frameset> element.

Table 9-1. The available attributes for the <frameset> element

Attribute

Value

Description

cols

Pixels

%

*

This attribute defines the number of columns in a frameset as well as their sizes.

rows

Pixels

%

*

This attribute defines the number of rows in a frameset as well as their sizes.

Whereas the <frameset> element defines the basic structure of the page, the <frame> element defines the details of each subwindow in the page. You specify these pages in the <frame> element with the src attribute. Within the <frame> element, most style attributes are defined, a list of which appears in Table 9-2.

Table 9-2. The available attributes for the <frame> element

Attribute

Value

Description

frameborder

0

1

This attribute defines whether a border is displayed around the frame.

longdesc

URL

This attribute is a URL to the long description of the frame that is used for browsers that do not support frames.

marginheight

Pixels

This attribute defines the top and bottom margins for the frame.

marginwidth

Pixels

This attribute defines the right and left margins for the frame.

name

frame_name

This attribute defines a unique name for the frame so that the Document Object Model (DOM) may identify it.

noresize

noresize

This attribute, when set, prevents the user from being able to resize the frame.

scrolling

yes

no

auto

This attribute defines the actions the scroll bars can take.

src

URL

This attribute defines the URL of the page to show in the frame.

Some browsers still do not support frames. To allow for this case, there is an optional <frameset> element: <noframes>. Within this element, you can place normal body content (including the body element) to inform the user of the circumstances, or to provide her with alternative pages to view the content. An example of a complete frameset appears in Example 9-1.

Example 9-1. A simple frameset layout that was and is popular with many web designers

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Simple Frameset Layout</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <meta name="author" content="Anthony T. Holdener III (ath3)" />
        <meta http-equiv="imagetoolbar" content="no" />
    </head>
    <frameset rows="15%, *, 5%">
        <frame id="topFrame" name="topFrame" noresize="noresize" scrolling="no"
            src="" />
        <frameset cols="25%, *">
            <frame id="navigationFrame" name="topFrame" noresize="noresize"
                scrolling="no" src="" />
            <frame id="contentFrame" name="topFrame" noresize="noresize"
                scrolling="no" src="" />
        </frameset>
        <frame id="bottomFrame" name="topFrame" noresize="noresize" scrolling="no"
            src="" />
        <noframes>
            <body>
                This application requires frames for complete use.  Please go to the
                <a href="index2.html">Text Version</a> of this application for a
                better experience.  Sorry for the inconvenience.
            </body>
        </noframes>
    </frameset>
</html>

Figure 9-1 gives you an idea of how this frameset would look.

The simple frameset layout, shown in Firefox

Figure 9-1. The simple frameset layout, shown in Firefox

With the frames of the page constructed, the developer must now develop the four XHTML pages that will make up these individual frames in the design. What is nice about this sort of layout is that the user can navigate without having to refresh all the frames; only the one active frame is refreshed.

Tip

For a properly validated application, only the <frameset> and <frame> elements can be used when the DOCTYPE has been declared in the page prolog. That DOCTYPE must be one of the Frameset DTDs.

The iframe Craze

Frames are a good start to a well-structured site, but as I said, they have some limitations. One of the biggest of these limitations, at least as far as DHTML is concerned, is that content cannot overlap from one frame to the next. Think of the setup of frames from Figure 9-1, with navigation being the left-side frame. If an application needs, say, a pull-out vertical menu, the menu has to fit inside the width of the frame. If it doesn’t, the frame will scroll to accommodate the objects inside it, at least if the proper attributes are set on the frame to allow it to handle objects larger than its width. This scenario also occurs on a site that has a drop-down menu in its top frame.

I am not slighting frames. They are useful for any site with content (e.g., a logo at the top, a menu or some other navigation widget, a footer, etc.) that does not change as the page content changes. This is a very good approach for keeping the site faster by cutting down on the amount of data the client must retrieve. As the site or application becomes more dynamic, however, different solutions must be found.

The <iframe> element was introduced with HTML 4 officially, though it was an Internet Explorer-only feature supported as of Internet Explorer 3.0. It functions the same way as traditional frames, except that it is an inline frame. This means an <iframe> element is part of the main page’s DOM document; therefore, you can place other elements in the document on top of or underneath the <iframe> element. Thinking about our vertical navigation box again, by using an <iframe> element to represent where the main document changes will be, we can have the static information (static in that the information does not need to be reloaded on every page) sit in the main document. Now, when submenus are pulled out of the main vertical menu, they can slide out on top of the <iframe> element, making the entire application appear to be seamless.

As the needs of DHTML applications increased, so too did the use of iframes within pages. It was an easy conversion from a framed site to an iframed site because the iframes could be programmatically manipulated in the same way as normal frames could. We will discuss this in more depth later in this chapter, so let’s leave programming an <iframe> element alone for now. There was never a great migration from frames to iframes, as I may have led you to believe from the title of this section, but more developers did take notice as more uses for the <iframe> element were discovered.

Most developers started to really use iframes for a process similar to Ajax. It was discovered that the <iframe> element could be hidden (much like the hidden frame trick), and calls could be made back and forth between client and server through this <iframe> element. This simulated asynchronous calling—well, it really was asynchronous, though it was a hackish sort of method—but the result was that more sophisticated programs started to pop up on the Web. The big difference between this method and the more modern Ajax approaches is that there is no good and reliable error handling when using a hidden <iframe> element. A considerable amount of parsing is involved in detecting errors in a page load using an <iframe> element because the server will return a page with the error, and the developer needs to either access the HTTP header that was sent or go through the page to find the error.

Another problem with the hidden <iframe> element is that there is no way to track the stage of the request’s calling process. So, there are downsides to not being able to write complicated and complex web applications like a developer can today with Ajax. When these tricks first came out, though, any advantage over traditional frames and simple HTML web sites was adopted—attempting to squeeze as much as possible out of the browser.

OK, so there was never an actual craze for iframes, but a good number of developers used iframes for some technique or other that would resemble Ajax today. Never forget that there are still good uses for frames and iframes. Unfortunately, their use does not follow the stricter nature of XML and XHTML.

XHTML and Frames

Frames and iframes, in a roundabout sort of way, became deprecated in XHTML 1.0 when it was introduced in January 2000. Section 4.10 of the XHTML 1.0 Recommendation deals with the elements with id and name attributes: <a>, <applet>, <form>, <frame>, <iframe>, <img>, and <map>. It states:

In XML, fragment identifiers are of type ID, and there can only be a single attribute of type ID per element. Therefore, in XHTML 1.0 the id attribute is defined to be of type ID. In order to ensure that XHTML 1.0 documents are well-structured XML documents, XHTML 1.0 documents MUST use the id attribute when defining fragment identifiers on the elements listed above.

The confusing part is that although it states that the name attribute is deprecated for <frame> and <iframe> elements, the XHTML 1.0 Frameset DTD still allows the name attribute. To make matters worse, XHTML 1.0 is the last recommendation to support the HTML frameset.

The Deprecated Ones

I should not have titled this section “The Deprecated Ones” so much as I should have titled it “HTML Frames Are Obsolete.” Either one would have caught your eye, right? I say this because even though XHTML 1.0 brought the HTML 4.01 Frameset DTD over to the XML version of HTML, it was only as a transitional device. The subsequent version of XHTML, XHTML 1.1, followed the XHTML 1.0 Strict DTD most closely, and frames and iframes no longer exist in these DTDs. There will be no support for HTML frames in XHTML 2.0, either. Instead, XHTML 2.0 will support the XFrames module.

The most current document for XFrames is the “8th Public W3C XFrames Working Draft” posted on October 12, 2005. XFrames and XHTML 2.0 are still in the more distant future. It will take time for browsers to adapt these recommendations into their cores. It will take even longer for developers to start to use the recommendations, because they must have something to develop for before they will begin. It is worth noting that however far off these recommendations seem to be, eventually frames as we know them will be obsolete.

Tip

Avoiding the use of deprecated features when following the World Wide Web Consortium (W3C) Recommendations satisfies the requirements of the following Web Accessibility Initiative-Web Content Accessibility Guidelines (WAI-WCAG) 1.0 guideline:

  • Priority 2 checkpoint 11.2: Avoid deprecated features of W3C technologies.

If Frames Are a Must

If the use of frames is absolutely necessary, and it really does not matter why, the DOCTYPE that you choose to implement will say a great deal about your commitment to moving technology forward or letting it stagnate. You may feel that is a little harsh, but in all fairness, the Web has proven that its choice to move slowly toward more XML implementations is no mere fancy of a few programmers. There is no reason why, at the very least, a developer should not choose to use the XHTML 1.0 Frameset DTD and program to its standards. There is also no reason why the application’s individual frames should not be set to XHTML 1.0 Strict DTD and programmed to its standards.

It would be better, at least in terms of the labor involved in upgrading a page, to do away with frames and use iframes instead. You would still need to use the XHTML 1.0 Frameset DTD, but more of an application could be structured for the more dynamic approaches. This would most assuredly cut down on time and costs when it’s necessary to do away with the iframes as well. At least if iframes are being used in an application, they are the only pieces that need to be changed, because the rest of the site should already be in the main document. A <div> element can then easily replace the <iframe> element in the document, and the coding changes can begin from there.

Using iframes As Frames

When you decide to use an <iframe> element instead of frames, it is helpful to understand the similarities and differences between the two. Essentially, the developer will want to treat the <iframe> element in the same way he treated the <frame> elements to minimize the amount of code that will need to be changed. The <iframe> element is treated as two different entities, and you can dynamically modify the element with either one. You can access the <iframe> element both as an object and as a frame.

It is important to understand this difference, and the fact that treating the <iframe> element in one way or the other is purely a personal decision. You may prefer the DOM syntax for manipulating a <frame> element. Likewise, you may want to treat the <iframe> element as an object, because that is what you are more comfortable doing.

The most common way to access a frame is through its name attribute from the document.frames[] array of elements. For instance, accessing the page using frame syntax would look something like this:

document.frames['myIframe'].location.href

To access this page while treating the iframe as an object, you access the <iframe> element by its id attribute; the syntax might look like this:

document.getElementById('myIframe').src

Treating an <iframe> element like a frame gives you all the properties that would be associated with a <frame> element—in the example, this was the location.href property. This is true when treating the <iframe> element as an object as well—the src property was used to access the page.

Tip

An interesting feature of the current DOM is that dynamically created <iframe> elements cannot be accessed as frames. Instead, they must be accessed as an object through their id attribute.

All modern browsers support both methods for manipulating an <iframe> element. The best advice I can give when you’re using <iframe> elements is to make sure that both the name and id attributes are used to define the element. This way, if you need to use one method over the other, it is as easy as switching the syntax. Most browsers require the name attribute to treat the iframe as a frame, because the name attribute allows the DOM to add the element to the frame tree. Such is the case with treating the <iframe> element like an object. Even when traversing a tree to get the element, some browsers require the id attribute to treat it like an object.

When you use an iframe as an object, you bring yourself closer to the idea of using Ajax for changing parts of a page. This, in turn, will make the transition smoother when you next move to XFrames and XHTML 2.0. Even without moving on, it is important to treat the <iframe> element as an object. This is simply because applications are now very dynamic, and you do not want to handcuff yourself by not being able to create a dynamic <iframe> element from within your JavaScript code.

The Magic of Ajax and a DIV

As we already discussed, frames have their disadvantages with dynamic sites and DHTML, and iframes are a solution that works around these problems. iframes are deprecated, however, and will no longer be a part of newer XHTML specifications. That is OK, as there is the alternative that will come with XHTML 2.0 in XFrames, although modern browsers most likely will not support this anytime soon. In the meantime, there is another method for producing the same kind of effect as iframes without actually using them. This method is to use Ajax and a <div> element.

With the proper CSS rules on the <div> element, the <div> will seamlessly drop in where the <iframe> element was, and the rest of the site will look the same. The behind-the-scenes wiring for the application will need to be modified, but if the iframes were treated as objects and not as frames, even these changes will not be too difficult. The major work concerns the addition of the Ajax code to handle what was simply changing the src or location.href attribute with iframes. Even this should not be too hard a switch, as I hope that by now using Ajax is becoming more natural to you.

Laying Out the “Frame”

Your first decision when using a <div> element instead of an <iframe> element is how it should be styled. You should base this decision on whether you want it to look like the <iframe> element or you want to make it look a little more like Web 2.0. This decision has no bearing on the Ajax code that will go behind the <div> element to manipulate it; it is merely aesthetic.

For example, the following CSS rules will style the <div> element to look like a standard <iframe> element, as you can see in Figure 9-2:

div.fakeIframe {
    border: 2px inset;
    height: 400px;
    overflow: auto;
    width: 500px;
    z-index: 500;
}
A <div> element styled like a standard iframe element

Figure 9-2. A <div> element styled like a standard iframe element

This boring <div> element looks exactly like an <iframe> element without any associated style. The <div> element looks exactly like an <iframe> element configured like this:

<iframe id="myIframe" name="myIframe" src="content.html" height="400px"
        width="500px" scrolling="yes" frameborder="1">
    Your browser does not support iframes.  Click
    <a href="alternative.html">here</a> for an  alternative.
</iframe>

However, more options with using a <div> element can make the application look more modern. For example, the developer can change the size of the margin or padding within the <iframe> element. There is no capability to do this with an <iframe> element. The background-color and color of the <div> element can also be changed, and all content that is put into the <div> element will take on these attributes; with an <iframe> element, every page would have to be individually styled, making any themed-based functionality more difficult to maintain.

The most important CSS rules that need to be put on the div element are:

overflow: auto;
z-index: 500;

These rules allow for scrolling when content gets too large for the configured dimensions of the <div> element, and keeping the <div> element in the proper order on the page. Figure 9-3 shows a better example of what you can do with a <div> element.

Using CSS to style a <div> element to make it look more modern

Figure 9-3. Using CSS to style a <div> element to make it look more modern

Inserting Content

Creating and styling the <div> element is only a small part of replacing an <iframe> element. The more important part is to make it functional by being able to place content from other pages within it. You add the new content to the <div> element through Ajax calls and a little XML DOM manipulation. You should also try to maintain an accessible site while still utilizing Ajax.

With web accessibility and WCAG guidelines in mind, the ideal way to make this site work is to write all the pages as you would with a normal framed site—in other words, make sure each page is actually a complete XHTML page that can stand on its own if it needs to. This way, if the client being used does not support the JavaScript needed to make this work, the full page can still be loaded like a normal page through <a> elements in the pages. For example:

<a href="page_one.html"
        onclick="return openPageInDIV(this.href, 'myFakeIframeDiv'),">
    Page one
</a>

As long as the openPageInDIV( ) function returns false, when the link is clicked, the <div> element can get the contents of page_one.html. But if the JavaScript does not function because the browser does not support it, the link will still work to page_one.html, and the site remains accessible.

That is the accessibility part of this technique, and now we can concentrate on the Ajax part of it. There is not much to this technique. The important part is getting a function that can accept as input the page to go to and the <div> element to put it in. Example 9-2 shows how you could code such a function.

Example 9-2. A function to put content into a <div> element

/**
 * This function, openPageInDIV, makes an XMLHttpRequest to the passed /p_page/
 * parameter and the <body> of the page is then imported and appended into the
 * passed /p_div/ parameter.  Using the custom document._importNode( ) method
 * ensures with most browsers that any attribute events that are contained in the
 * <body> will fire when called upon.  For other browsers, like Internet Explorer,
 * setting the /p_div/'s /innerHTML/ equal to itself does the trick.
 *
 * @param {String} p_page The string filename of the page to get data from.
 * @param {String} p_div The string /id/ of the <div> element to put the data into.
 * @return Returns false, so that the <a> element will not attempt to leave the page.
 * @type Boolean
 */
function openPageInDIV(p_page, p_div) {
    var where = $(p_div);

    new Ajax.Request(p_page, {
        method: 'get',
        onSuccess: function(xhrResponse) {
            var newNode = null, importedElement = null;

            /* Get the body element...all of its children are what we are after */
            newNode =
                xhrResponse.responseXML.getElementsByTagName(
                'body')[0].childNodes[0];
            /* was there any whitespace in the document? */
            if (newNode.nodeType != document.ELEMENT_NODE)
                newNode = newNode.nextSibling;
            /* Is there a node to import? */
            if (newNode) {
                importedNode = document._importNode(newNode, true);
                where.appendChild(importedNode);
                if (!document.importNode)
                    where.innerHTML =  where.innerHTML;
            }
        },
        onFailure: function(xhrResponse) {
            where.appendChild(document.createTextNode(xhrResponse .statusText));
        }
    });
    return (false);
}

This example probably looks a bit like Example 8-8 from Chapter 8; it is similar, but I have thrown a slight curve ball here. The importNode( ) function from Example 7-8 in Chapter 7 that is applied to the code in Example 8-8 works fine as long as the document being imported contains no event attributes. If there are event attributes—onclick, onmouseover, onload, and so on—they will be attached to the appropriate element, but will not register the events and make them available to the client’s DOM.

In fact, with a little experimentation, you would find that the DOM importNode( ) method that DOM Level 2-compliant browsers implement does not handle this either. So, what do we need to do? Obviously, an importNode( ) method that does not properly set up events is no good to us, and we need to write a function to handle this for us. This is where the document._importNode( ) method will come into play, which is shown in Example 9-3.

Warning

The interesting thing about the importNode( ) DOM method is that not only are events not registered with the DOM when these attributes are imported, but the style is not registered either. Say the following XHTML was imported using importNode( ):

<div id="importMe" onclick="alert('Hello world clicked'),">
    Hello <b>world</b>!
</div>

With this code, the onclick event will not register, and clicking on the <div> element in the browser will have no effect. Furthermore, the “world” text in the <div> element will not be in boldface either. The style for the <b> element is not registered for the imported elements in the DOM.

Example 9-3. A cross-browser importNode( ) that registers events and style

/**
 * This method, _importNode, is a replacement for the DOM /document.importNode( )/
 * method.  To ensure that any attribute events that are contained in the document
 * are fired when requested, it should go through this method instead.  The standard
 * /importNode( )/ does not set the event handlers for events set as attributes in an
 * imported document, nor does it place style toward elements that should do such
 * things in the browser.  An additional requirement is necessary for browsers like
 * Internet Explorer after the document has been imported - the /innerHTML/ of the
 * document where the import took place must be set equal to itself to invoke the
 * HTML Parse in the browser which will attach the event handlers.
 *
 * document.getElementById('myDiv').innerHTML =
 *     document.getElementById('myDiv').innerHTML;
 *
 * @param {Node} p_node The node to import into the main document,
 * @param {Boolean} p_allChildren The indicator of whether or not to include child
 *     nodes in the import.
 * @return Returns a copy of the imported node, now as a part of the main document.
 * @type Node
 */
document._importNode = function(p_node, p_allChildren) {
    /* Find the node type to import */
    switch (p_node.nodeType) {
        case document.ELEMENT_NODE:
            /* Create a new element */
            var newNode = document.createElement(p_node.nodeName);

            /* Does the node have any attributes to add? */
            if (p_node.attributes && p_node.attributes.length > 0)
                /* Add all of the attributes */
                for (var i = 0, il = p_node.attributes.length; i < il;)
                    newNode.setAttribute(p_node.attributes[i].nodeName,
                        p_node.getAttribute(p_node.attributes[i++].nodeName));
            /* Are we going after children too, and does the node have any? */
            if ( p_allChildren  && p_node.childNodes && p_node.childNodes.length > 0)
                /* Recursively get all of the child nodes */
                for (var i = 0, il = p_node.childNodes.length; i < il;)
                    newNode.appendChild(document._importNode(p_node.childNodes[i++],
                        p_allChildren));
            return newNode;
            break;
        case document.TEXT_NODE:
        case document.CDATA_SECTION_NODE:
        case document.COMMENT_NODE:
            return document.createTextNode(p_node.nodeValue);
            break;
    }
};

For any of the modern browsers (I should just say for any browser that is not Internet Explorer), executing the document._importNode( ) method properly registers events and style properties in the DOM, allowing for any imported nodes to behave as expected. With Internet Explorer, however, this code does not, for whatever reason, register the event attributes. It does, however, register all of the style properties.

Tip

The article “Cross-Browser Scripting with importNode( )” explains the DOM’s importNode( ) method and why Example 9-3 is important. Read it on the A List Apart web site, at http://www.alistapart.com/articles/crossbrowserscripting.

The imported nodes in Internet Explorer must be put through the HTML parser a second time before the event attributes are registered with the DOM. That is why the following code is in Example 9-2 after the imported nodes are appended to the existing document:

 if (!document.importNode)
     document.getElementById('divContainer').innerHTML =
         document.getElementById('divContainer').innerHTML;

Instead of checking for document.importNode, any of the other methods for sniffing out Internet Explorer will also work. Also remember that Internet Explorer does not natively define document.ELEMENT_NODE or any of the other node types. These must be defined before Example 9-2 or Example 9-3 will function correctly in Internet Explorer. Regardless of browser, Figure 9-4 shows the results of this method. The end user will never know how the content ended up on the page, as it acts in the same way functionally as it would using an <iframe> element.

The <div> element filled with the contents of another page

Figure 9-4. The <div> element filled with the contents of another page

Figure 9-4 shows how a page might look if it had one <div> element on top of another <div> element, in this case a PNG image of a jungle overlaying a site I resurrected specifically for this chapter: Cyber-Safari Internet Cafe (found on the Wayback Machine at http://www.archive.org/web/web.php). You can achieve the same effect using <iframe> elements; however, the Ajax technique makes for easy manipulation from within one DOM document.

Disregarding the slight hiccups involved in importing documents into existing documents, placing content into a <div> element using Ajax is straightforward and simple to do. The improvements to the importNode( ) method are relied upon greatly with Ajax applications, and it should not surprise you when you see a reference to Example 9-3 every now and again throughout the rest of this book.

Page Layout

So far, this chapter discussed frames, iframes, and how to use Ajax and <div> elements to produce pages that work in the same basic way. All of this really boils down to the structure of the page, or how the page is laid out. This section of the chapter will not cover where elements should be presented on a page. That is certainly not in the scope of this book. Instead, we need to evaluate how the structure of a page can be more or less dynamic and flexible.

Think About Being Dynamic

It is extremely important for Ajax developers to think about the dynamic nature that their pages will take on. It is fine and dandy to create some widgets that open up, slide out, or appear and disappear at the click of a button. Unless those widgets are placed correctly, however, the page might not function properly or parts of it may become inaccessible. To avoid this, you should think about how to make all of the individual pieces of the page independent of one another. This way, you can move things around without degrading the widget in the process.

Warning

The placement of dynamic widgets on a page is not the biggest issue a developer will face when dealing with dynamic content. A much more important issue is how dynamic data could break the application accidentally or maliciously when the data received is not what is expected.

An easy way to accomplish this sort of structure is to make sure all objects that are placed in the page have a wrapper or container around them. Wrappers enable the parts to be moved using CSS without messing around with the structure of the page. The wrapper makes the object independent by separating it from everything else. For example:

<div id="headerContainer">
    <div id="logoContainer">
        <!-- Logo content goes here -->
    </div>
    <div id="menubarContainer">
        <!-- Menu bar content goes here -->
    </div>
    <div id="">
        <!-- Breadcrumb content goes here -->
    </div>
</div>
<div id="contentContainer">
    <!-- Page content goes here -->
</div>

In this example, the menu bar, logo, and breadcrumb objects are separated from one another by their individual wrappers. These objects are then wrapped in another wrapper that separates them from the content object of the page. The content object is then likely to have many of its own objects that are also individually wrapped. For a better picture of this technique, see Figure 9-5.

A diagram showing a wrapper or container technique

Figure 9-5. A diagram showing a wrapper or container technique

This technique has been around for some time, though it is still not used as much as it should be. Perhaps as more designers and developers cross paths making these new Ajax applications, the technique will begin to make more sense to both parties involved in the design process. The theory of abstracting structure to many containers or wrappers has working models on the Internet, where the structure and presentation are separated so that the same structure can be shaped into an endless number of possible presentations.

The Proven Theory

Of course, the popular CSS Zen Garden site (http://www.csszengarden.com/), whose structure and presentation are completely separated, proved this theory. Dave Shea created the Zen Garden around 2001 after being inspired by Chris Casciano’s Daily CSS Fun (http://placenamehere.com/neuralustmirror/200202/) and the Hack Hotbot contest in 2003 (http://web.archive.org/web/20030406032202/http://hack.hotbot.com/). The goal of the CSS Zen Garden was to demonstrate what could be accomplished with CSS from a design standpoint.

By taking some simple XHTML markup, graphic designers were invited to create a design relying on manipulating the CSS and not the XHTML. Figure 9-6 shows what the structure of this page looks like without any CSS attached to it.

The unstyled CSS Zen Garden page

Figure 9-6. The unstyled CSS Zen Garden page

By adding CSS style rules to this basic structure, you really have no limitations on what you can accomplish visually with this method. As examples, Figure 9-7 shows what the CSS Zen Garden page looks like with the original style attached to it, and Figure 9-8 shows an excellent example of just how far CSS in design has come.

The default CSS Zen Garden site created by Dave Shea

Figure 9-7. The default CSS Zen Garden site created by Dave Shea

The CSS Zen Garden styled with Mozart by Andrew Brundle

Figure 9-8. The CSS Zen Garden styled with Mozart by Andrew Brundle

I know the CSS Zen Garden is about visual style, but it has applications in the Ajax world as well. Remember that Ajax allows for any part of a site to be changed dynamically, and there is no reason to be stuck in the same square world with Ajax that we inhabited not so long ago with frames and iframes.

Let CSS Be Your Guide

The CSS Zen Garden demonstrates the importance of separating our structure from our presentation, simply by showing the number of ways we can lay out the same structure using CSS rules. Everything about the CSS Zen Garden teaches us that structure does not dictate an application so much as style does. Anyone who develops a web application must expect it to be dynamic, and the easiest way to make it dynamic is to rely on CSS. However, that is not the only lesson I want you to learn regarding CSS. The important lesson to take away is focused more on the structure and not on all of the fancy presentation.

The structure that was used for all of the CSS examples available on the site is broken down into smaller components. By using and manipulating these smaller components, you begin to see the leverage you can wield. In the case of the CSS Zen Garden, the components were used to move around the structure of the page for whatever presentation purposes were required. But for Ajax, using the same technique of separating the structure into more manageable and smaller components—what we were calling wrappers or containers earlier—will allow us to dynamically control small, individual portions of the application from within our Ajax and JavaScript framework.

Presentation is important for the application, so when a developer begins a new Ajax application project she must be aware of presentation, but she must also be aware of the keys to manipulation when smaller components are used. The CSS Zen Garden teaches us a lot. It is a fine example of compartmentalizing structure into more useful pieces. This is the same approach that every Ajax application must take. If it does not, a developer will find it difficult to manipulate the pieces that she wishes, and she may have to rely on hacks to get effects that could have been more readily available had the program or application been created that way in the first place. As we move on in this book, we will let CSS be our guide. We will look at everything in the application, not as a whole but as individual pieces, paving the way for the most fluid and dynamic applications possible today.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset