Using frames effectively requires more than just knowing the HTML tags. This section provides a few pointers and tricks for framed documents.
Designing a web page to be part of a framed document doesn't guarantee that it will always be viewed that way. Keep in mind that some users might end up looking at one of your pages on its own, out of the context of its frameset (this is possible if a search engine returns the URL of the content, for example). Since frames are often used for navigation, this orphaned content page could be a big, fat dead-end for a user.
For that reason, you should try to design your content pages so that they stand up on their own. Adding a small amount of redundant information to the bottom of each page can make a big difference in usability. First, indicate the name of the site with a link to its home page on each content document. This helps to orient a newcomer who may have just dropped in from a search engine.
It is important to pay particular attention to the navigational options available on content pages viewed without their frameset. At the very least, provide a small link on every page to a more appropriate (and framed) starting point, such as the top level of your site. Be sure to set the target="_top" attribute so the link won't load the home page frameset within the current frameset.
As a backup measure, you could use JavaScript to ensure that a page is always viewed in its original frameset. This technique is discussed under Section 14.7.9, "Keeping Pages in Their Frames" later in this chapter.
In most cases, it is not appropriate to load whole external sites into the context of another framed document. By default, any link within a frame loads the new document into that same frame. To prevent external links from loading into the current frame, be sure to add target="_top" to all your external links; the new site will open in the full browser window. As an alternative, set the target to "_blank" to open the link in a new browser window.
Search engines all work differently but pretty much uniformly do not understand frames or any content within a <frameset> or <frame> tag. This means search engines will not find any links that require burrowing through a site for indexing purposes, and all the content of your framed site will be missed.
There are a few measures you can take to make your site more friendly to search engines:
Include content in the frameset document. Search engines read content within the <noframes> tag. It is a good idea to make it as descriptive as possible so search engines have something to index (instead of just "you need frames to see this site"). Adding a link within the noframes text to the HTML file containing all your navigational links helps search engines (and humans!) get to the content of your site without relying on the frameset.
Use descriptive titles. Titles are the most important things that search engines index, so use descriptive titles on all content documents. Document titles do not display when the document is loaded into a frame, so it doesn't affect your frame design.
Use <meta> tags. Although not all search engines use <meta> tag information, they can be a useful tool for those that do. If your top-level frameset document contains limited content within the <noframes> tag, you can add a site description and keywords to the page via <meta> tags for the search engine to index. The <meta> element is fully discussed in Chapter 9, "Structural HTML Tags". The following is a sample of standard <meta> tags used to aid search engines:
<HEAD> <TITLE>Littlechair Studios</TITLE> <META name="description" content="Jennifer Niederst's resume and web design samples."> <META name="keywords" content="designer, web design, training, interface design"> </HEAD>
For more information about search engines and how they work, see the Search Engine Watch site at http://www.searchenginewatch.com (from which the previous information was gathered).
Ordinarily, a link can target only one frame, but there are a few options for creating links that change the contents of two frames at once. One involves simple HTML and the others use JavaScript controls.
In HTML, you can only load one document with a link, and that document can occupy just one window or frame. Loading two or more frames (essentially two documents) with a single click requires a bit of fakery. What you're actually doing is loading a single document that is divided into frames itself. What the user sees is a number of frames being replaced at once.
This effect cannot be achieved by nesting framesets as shown in Figure 14-4. Instead, the nesting happens as a product of a framed external document loading into a single frame.
For instance, the following code creates a frameset with two frames: a narrow "top" frame and a "main" bottom frame. This frameset is called top.html.
<FRAMESET ROWS=50,*> <FRAME SRC="toolbar.html" NAME="top"> <FRAME SRC="two_frames.html" NAME="main"> </FRAMESET>
The bottom frame displays the contents of a document with two vertical frames called two_frames.html, shown here:
<FRAMESET COLS=250,*> <FRAME SRC="left.html" NAME="leftframe"> <FRAME SRC="right.html" NAME="rightframe"> </FRAMESET>
It is assumed that there are a number of documents like two_frames.html that can be accessed by links in the top frame. Each link from the top frame loads one document in the "main" frame, but the contents of two frames change at once.
Of course, this method works only for neighboring frames.
Adding an onClick JavaScript command within the link allows the browser to load documents into two frames based on one mouse click.[7] For this example, imagine a document that contains two frames, a list of options on the left and the contents in the main window on the right. We want a link in the left frame to change the contents on the right, but also to load a new list of options (perhaps with the current choice highlighted) into the left frame. The code is quite simple:
[7]This tip was gathered from Webmonkey, an online magazine for web developers; see http://www.webmonkey.com.
<A HREF="content.html" onClick="window.self.location='newlist.html'" TARGET="display">Chocolate</a>
The text in bold is the JavaScript line that tells the browser to load newlist.html into the same window/frame as the link. The remaining code is the standard HTML link that will load content.html into the display frame on the right.
Another (and more robust) method for changing two frames with one click uses a function that changes the contents of two frames (named "toolbar" and "main"), as shown in this sample code:
<SCRIPT LANGUAGE="JavaScript"> <!-- function changePages (toolbarURL, mainURL) { parent.toolbar.location.href=toolbarURL; parent.main.location.href=mainURL; } --> </SCRIPT>
Within the anchor tag, the additional code provides the URLs for the documents that will be used in the script (and loaded into the respective frames), as shown in the following example:
<A HREF="javascript:changePages('toolbar_document2.html', 'main_document 2.html');">
It is important to keep in mind that if JavaScript is turned off in the user's browser, this link will have no effect; therefore, you should use this method cautiously.
Inline (floating) frames are really cool, but unfortunately, they are not supported in all browsers (Navigator 4.7 and earlier lack support). The following code gives the effect of an inline frame using standard frames tags (but, of course, without all the text-wrap functionality). It creates a scrolling frame that is always centered in the browser window, regardless of how the window is resized, as shown in Figure 14-10.
<FRAMESET COLS="*,130,*" NORESIZE BORDER=0 FRAMEBORDER=0 FRAMEBORDER=no FRAMESPACING=0> <FRAME SRC="black.html" SCROLLING=no> <FRAMESET ROWS="*,90,*" NORESIZE BORDER=0 FRAMEBORDER=0 FRAMEBORDER=no FRAMESPACING=0> <FRAME SRC="black.html" SCROLLING=no> <FRAME SRC="pix.html" SCROLLING=auto MARGINWIDTH=0 MARGINHEIGHT=0> <FRAME SRC="black.html" SCROLLING=no> </FRAMESET> <FRAME SRC="black.html" SCROLLING=no> </FRAMESET>
The middle column setting in the first <frameset> is the width of the window in pixels. The middle row setting in the nested <frameset> gives the window's height. You can change the size of the window by adjusting these settings. You can also set the scrolling function of the frame in its <frame> tag.
In this example, all the remaining frames are filled with an HTML file with no contents and a black background. Of course, these frames could contain actual content as well.
Some sites may link to your site and load it into a single frame in their interface. If you really don't want to see your site squished into someone else's frame, you can add this tricky (yet simple) JavaScript to the <head> of your document, which makes your page always load into the top level of the browser window. (This script works for Netscape Navigator 3.0 and higher and Internet Explorer 3.0 and higher.[8])
[8]Thank you to Vince Heilman for contributing this script.
<SCRIPT LANGUAGE="JAVASCRIPT"> <!-- Hide from old browsers if (top != self) top.location.href = location.href; // Stop hiding from old browsers --> </SCRIPT>
"Preloading images" refers to methods used to download images and store them in the cache before they actually need to be displayed on the page. One method for doing this is to place all the images you'd like to download in a framed document that is hidden from view. The images download and are cached when the first frameset is loaded, but they won't be seen until the user links to a visible page that includes them.
The trick is to create a frameset with two rows (or columns). Set the size of the first row to 100% -- this is the frame that will be used to display your first page. In the second row, the one that gets squeezed out of existence, specify the document that contains your images.
<FRAMESET ROWS="100%,0" NORESIZE BORDER=0 FRAMEBORDER=0 FRAMEBORDER=NO FRAMESPACING=0> <FRAME SRC="firstpage.html"> <FRAME SRC="thepictures.html"> </FRAMESET>
You can put a bunch of images there, but keep in mind that it's not a free download, just a predownload, so all the same rules about minimizing file sizes apply. There's always the chance that the user might request one of the images (via a link or by moving to a web page that contains it) before they've all arrived.
While WebTV technically supports frames (i.e, it can display the information in a framed document), it does so by converting the framed document into a large table. Each "frame" (more like a table cell) displays the entire contents of the frame source. If a frame contains an HTML document that is quite long, the resulting "frame" in WebTV will be extended to display the entire file, regardless of the specified frame size. There is no scrolling function in WebTV.
In addition, WebTV "frames" do not remain in a fixed position like normal frames, but instead move off the screen when users page down through the content.
Frames done with JavaScript links (such as those discussed previously in this chapter) will break navigation in WebTV. If your site targets WebTV users, be sure to either keep frames simple or not use them at all.
For more information on WebTV's handling of frames, see http://developer.msntv.com/Support/faq.asp#HTML.
In some cases, users might come across a content document independent of the frameset that is intended to contain it (such as from a link in search engine results). To prevent your content pages from appearing out of context, use this JavaScript code in the head of any document that needs to appear in a frameset:
<SCRIPT LANGUAGE="JavaScript"> <!-- if (top.location == self.location) { self.location.replace("frameset.html") } // --> </SCRIPT>
The first line of the script checks to see if the topmost frame of the current window is the document. If it is, the second line of the script instructs the browser to replace the document with the frameset document (frameset.html in this example, but fill in your own file name in this location).
Some framed page designs rely on precise pixel measurements to achieve a desired effect. While Internet Explorer (all versions) and Netscape 6 do not have a problem rendering frames with pixel accuracy, this is not the case for Netscape Navigator Versions 4.7 and earlier. They handle frames in a way that makes it nearly impossible to get the frame sizes you specify.
The reason is that Navigator's frame code (developed way back for Version 2.0) records all frame dimensions in percentages. Any pixel measurements provided in the rows or columns attributes are calculated as a percentage of the available screen space and then rounded off to the nearest percentage point. The rounding results in the rendered frame being up to 12 pixels different (usually smaller) than the specified size. If alignment is crucial for your design, 12 pixels of shift may be unacceptable.
Unfortunately, there is not much that you can do about this other than to use JavaScript to specify a new window with known innerWidth and innerHeight measurements, and then base your frame measurements on even percentages of those values. Otherwise, you may want to simply avoid pixel-dependent frame designs.
On the bright side, this problem was fixed in Netscape 6, and the older versions of Navigator make up an ever-diminishing percentage of overall browser use. Eventually this will be a non-issue, but in the meantime, just be aware that if your frames are misbehaving, it may be Navigator and not your code that's to blame.[9]
[9]This tip taken with permission from CNET's Builder.com. It appeared in an article by Paul Anderson entitled "Frame Quirks in Navigator" (12/6/99). You can read the original at http://www.builder.com/Authoring/Tagmania/120699/index.html.
Copyright © 2002 O'Reilly & Associates. All rights reserved.