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.
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.
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.
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.
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 |
---|---|---|
|
| This attribute defines whether a border is displayed around the frame. |
|
| This attribute is a URL to the long description of the frame that is used for browsers that do not support frames. |
| Pixels | This attribute defines the top and bottom margins for the frame. |
| Pixels | This attribute defines the right and left margins for the frame. |
|
| This attribute defines a unique name for the frame so that the Document Object Model (DOM) may identify it. |
|
| This attribute, when set, prevents the user from being able to resize the frame. |
|
| This attribute defines the actions the scroll bars can take. |
|
| 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.
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.
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.
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 iframe
s within pages. It
was an easy conversion from a framed site to an iframe
d site because the iframe
s 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 iframe
s, 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 iframe
s 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 iframe
s, but a good number of
developers used iframe
s for some
technique or other that would resemble Ajax today. Never forget that
there are still good uses for frames and iframe
s. Unfortunately, their use does not
follow the stricter nature of XML and XHTML.
Frames and iframe
s, 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.
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 iframe
s 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.
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 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 iframe
s 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 iframe
s as well. At
least if iframe
s 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.
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.
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.
As we already discussed, frames have their disadvantages with
dynamic sites and DHTML, and iframe
s are a solution that works around
these problems. iframe
s 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 iframe
s 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 iframe
s 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 iframe
s. Even this should not be too hard a
switch, as I hope that by now using Ajax is becoming more natural to
you.
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; }
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.
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.
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.
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.
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.
So far, this chapter discussed frames, iframe
s, 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.
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.
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.
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.
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.
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.
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 iframe
s.
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.
44.220.184.63