Designing with Frames – an Introduction

Kevin Yank
Tweet

Frames are a feature of HTML that allows you, as the author, to control the layout of a Website in the user’s browser. Specifically, frames allow you to divide the browser window into rectangular sections that can be treated as if they were separate browser windows. They can be scrolled and resized, and loaded with different Web pages. These sections are called frames.

Although they were not recognized by the W3C as an official aspect of any HTML specification until the current HTML 4.0, frames have been supported by the two mainstream browsers since their early versions (Netscape Navigator since version 2.0, Microsoft Internet Explorer since version 3.0). This fact has helped them become one of the most commonly-used (and misused!) "tricks" to spruce up a Website design.

Used properly, frames can add structure and ease of use to a site. Used badly, frames can make a site look crowded, patchy, and sometimes downright unusable on some hardware setups. Their most common use, the creation of a non-scrolling menu bar down the left-hand side of the window, is usually a good idea; however, if you try to cram too much information into that menu bar, some users with smaller monitor sizes won’t be able to access the items at the bottom of your menu. Misguided frame layouts such as these have earned a special place in the list of pet peeves of most seasoned Web designers. For this reason, it is important that you not only learn the strengths of frame-based layouts, but also their weaknesses.

For the purposes of this article, a basic understanding of HTML is assumed. Some knowledge of JavaScript and its principles would also be helpful in the final sections, but is not required. Should you wish to read up on either of these languages, I recommend the Beginners’ HTML series, and the Javascript 101 tutorial.

Basic Frames

In this section, we’ll create a very basic set of frames. We will then modify some of their properties to make them work and look the way we want them to.

Our First Frameset

People are often surprised at how easy it is to create a Web page that contains frames. Each rectangular section into which you want to divide the browser window is called a frame. To define the set of frames you intend to appear in your Website, all you have to do is write a special HTML file that defines the size, position, and initial contents of each frame. You must then write separate HTML files for the contents of each frame, just as you would for a normal browser window.

Don’t worry if this isn’t making sense to you just yet… I’ll get back to these ideas in a moment. For now, let’s concentrate on the HTML file that defines your set of frames. This is simply called the frameset, and looks something like this:

<HTML>  
<HEAD>  
<TITLE> Our First Frameset </TITLE>  
</HEAD>  
 
<FRAMESET>  
<FRAME>  
<FRAME>  
...  
</FRAMESET>  
 
<NOFRAMES>  
...  
</NOFRAMES>  
 
</HTML>

Note that this HTML file doesn’t contain a <BODY> tag. Notice also the use of three new tags in this file:

  • <FRAMESET>
  • <FRAME>
  • <NOFRAMES>

The <FRAMESET> tag takes the place of the <BODY> tag in a "normal" HTML file, and is used to provide information about the set of frames that will appear in the browser window. Information such as how the window is to be divided up, how many frames there will be, and any other information that relates to the set of frames as a whole is specified using this tag.

Let’s use a concrete example. Suppose you wanted to create a Web page with a horizontal division right across the middle of the browser window. In other words, you’d have two frames, each occupying 50% of the vertical space in the window. This way of thinking about frames as divisions of the available space is important, because this is how the <FRAMESET> tag works:

<FRAMESET ROWS="50%,*"> 

This simply says to the browser:

"I want a set of frames that divides the window into rows. Of the available space, the first frame will occupy 50%, and the second will occupy whatever is left."

Notice especially the fact that the asterisk ("*") stands for "whatever is left". More on this later.

To place the division vertically down the middle of the page, you would simply type the following:

<FRAMESET COLS="50%,*"> 

Note that for the sake of brevity, HTML takes "COLS" to mean "columns". That is, COLUMNS="50%,*" will not work!

Now, as you may have guessed, the <FRAME> tag provides information specific to each individual frame. You will have to enter a number of <FRAME> tags that’s equal to the number of frames you specified with the <FRAMESET> tag. In our simple example, this tag will be used simply to tell the browser which HTML file to load into each frame, as follows:

<FRAME SRC="topframe.html">  
<FRAME SRC="botframe.html">

So the first (top) frame in our frameset will be loaded with topframe.html in it, while the second (bottom) frame will contain botframe.html.

Finally, the <NOFRAMES> tag follows the <FRAMESET> tag, and is used to specify content to be displayed if the user’s browser is unable to display frames. Although this is becoming increasingly uncommon, many educational institutions still allow students to access the Internet on text-based terminals. Web browsers for this medium, the most popular of which is Lynx, are generally unable to display frames.

<NOFRAMES>  
<P>Sorry, but it appears you are using a Web browser  
that does not support frames. Click <A HREF="noframes/  
index.html">here</A> to access the non-frames version  
of our site.</P>  
</NOFRAMES>

The way the <NOFRAMES> tag works is by saying to any browser that does support frames: "Do not display this." As any Web browser that doesn’t support frames will not know any more about this tag that it will the <FRAMESET> and <FRAME> tags, it will simply ignore them all, and be left with the enclosed text to display. In the example above, I have provided a link to a version of the site that does not use frames. If this is not feasible, it is still good practice to include a note telling users of frames-incapable browsers that your site cannot be accessed using their browser.

Gathering all this together, we have our simple two-frame frameset.

See it in Action | View the Code

More on <FRAMESET>

As mentioned above, the <FRAMESET> tag is used to provide information on how the window should be divided up into frames. This is done using the ROWS and COLS attributes to define the rows and columns the window is to be divided into respectively.

These divisions can be defined in three ways: percentages, pixels, and ratios. These three methods can be clearly illustrated using a few examples.

<FRAMESET COLS="50,*,*"> 

In this example, the window will be divided into three columns; the first of which will occupy a width of 50 pixels. The second and third frames will each occupy half of the remaining space.

<FRAMESET COLS="50%,*,20%"> 

This example defines three columns, occupying 50%, 30% and 20% of the window respectively. The first and third have their percentages defined, while the second takes up the remaining 30% of the window.

<FRAMESET ROWS="3*,1*,2*"> 

This time the window will be divided into rows instead of columns. The first will take up half the height of the window, the second will take a sixth, and the last will take a third of the window. This may seem confusing at first, but think of it in terms of ratios. The window is divided into 6 equal parts (3+1+2=6). The first frame takes up 3 of them (three sixths is a half), the second one takes up 1 (a sixth), and the last will take the remaining two (two sixths is a third).

<FRAMESET ROWS="30,50%,2*,1*"> 

This time there will be four rows. The first frame will take up 30 pixels of the height of the window, while the remaining frames take up the rest. The second frame will take 50% of the total height of the browser window. The third and fourth frames take up the space that is left in a ratio of 2 to 1. That is to say, the second frame will take up twice as much space as the third.

It’s generally not recommended to mix the three methods like this. This method makes it very difficult for someone who reads your code to guess what it will look like ahead of time. In cases like this, I usually recommend using nested framesets for the sake of readability. More on this in a moment.

You are free to use either the ROWS or COLS attributes on their own, or together, to define a grid layout:

<FRAMESET ROWS="60,50%,*" COLS="1*,2*,3*">   
<FRAME SRC="frame1.html">  
<FRAME SRC="frame2.html">  
<FRAME SRC="frame3.html">  
<FRAME SRC="frame4.html">  
<FRAME SRC="frame5.html">  
<FRAME SRC="frame6.html">  
<FRAME SRC="frame7.html">  
<FRAME SRC="frame8.html">  
<FRAME SRC="frame9.html">  
</FRAMESET>

See it in Action | View the Code

If you need more flexibility in the definition of your layout, you can use a technique called nested framesets. As the name suggests, this involves placing framesets within framesets. For example, if you wanted a navigation bar 50 pixels wide down the left-hand side of your page, but you also wanted a 30 pixel-high title frame across the top of your page, you could use this:

<FRAMESET COLS="50,*">   
<FRAME SRC="menu.html">  
<FRAMESET ROWS="30,*">  
  <FRAME SRC="title.html">  
  <FRAME SRC="body.html">  
</FRAMESET>  
</FRAMESET>

Notice how the "inner" <FRAMESET> tag goes where a <FRAME> tag would normally go. You replace as many frames as you want with nested framesets, and you can even define framesets within framesets within framesets (and so on)!

See it in Action | View the Code

Besides ROWS and COLS, there are several other attributes to the <FRAMESET> tag that allow you to affect the way a frameset looks:

FRAMEBORDER="n"

Sets whether or not to display a 3D border between the frames. If n is 1, a 3D border will be displayed just as if this attribute had been left out. If n is 0, the border will be invisible. You can also use YES instead of 1, and NO instead of 0. This attribute works with Netscape and Internet Explorer versions 3 and later.

BORDER="n"

Sets the width of the 3D border between frames. n is a number of pixels. This attribute works with Netscape versions 3 and later, and Internet Explorer versions 4 and later.

FRAMESPACING="n"

Sets the amount of space between frames. n is a number of pixels. This lets you space out your frames even if you have chosen not to display a 3D border. This attribute works with Internet Explorer browsers only.

BORDERCOLOR="color"

Sets the color of the 3D border between frames. color is a standard HTML color (e.g. "RED", "#FFFFFF", etc.). This attribute works with Netscape 3 and above, as well as Internet Explorer 4.

Experiment with these yourself, but always keep in mind which browsers support the attributes you use, and which don’t. Also, make sure your frameset is usable on as many browsers as possible, so that people can access the most important part of your site — the content.

More on <FRAME>

As you are no doubt aware by now, the main function of the <FRAME> tag is to set the initial contents of each frame in your frameset. Like the <FRAMESET> tag, it also accepts several other attributes that allow you to change the way the individual frame works. Unless otherwise indicated, these attributes work in Netscape 2 and above, and Internet Explorer 3 and above.

NAME="name"

Allows you to set a name for your frame. name is a piece of text, usually enclosed in quotes. Giving your frame a name allows you to target it with hypertext links, and manipulate it using JavaScript. Examples of these techniques are shown in following sections of this article.

FRAMEBORDER="n"

Sets whether or not to display a 3D border around this frame. If n is 1, a 3D border will be displayed. If n is 0, the border will be invisible. You can also use YES instead of 1, and NO instead of 0. Using this in a <FRAME> tag will override the FRAMEBORDER attribute of the enclosing <FRAMESET>, if any. This attribute works with Netscape and Internet Explorer versions 3 and later.

NORESIZE

Keeps the user from being able to change the size of this frame by dragging its border with the mouse. The syntax is simply NORESIZE; it does not need to be assigned a value.

SCROLLING="value"

Defines whether or not scroll bars should be displayed in this frame. value may be YES, NO or AUTO. If YES, horizontal and vertical scroll bars will always be displayed, even if the contents of the frame are small enough to fit inside the frame all at once. If NO, scroll bars will never be displayed, even if the contents of the frame are too large to fit within the frame all at once. AUTO indicates that the frame should behave normally; displaying scroll bars only when the contents exceed the size of the frame.

NOTE: Unless you take special care, a frame that uses NORESIZE and SCROLLING=NO may present a problem for users with smaller screen sizes. Don’t use this combination unless you need to. If you do, be sure to test it on a 640×480 pixel screen to be sure it is still useable.

MARGINWIDTH="n"

Sets the amount of space between the left and right borders of the frame and its contents. n is a number of pixels. Internet Explorer browsers accept values of 0 or higher, but Netscape browsers only accept values of 1 or higher, and will take 0 to mean 1.

MARGINHEIGHT="n"

Sets the amount of space between the top and bottom borders of the frame and its contents. n is a number of pixels. Internet Explorer browsers accept values of 0 or higher, but Netscape browsers only accept values of 1 or higher, and will take 0 to mean 1.

TIP: If you want to have the contents of the frame flush against its edges, you must combine several techniques for different browsers. First, use a MARGINWIDTH and MARGINHEIGHT of 0 for Internet Explorer browsers. For Netscape 4, you must also set a MARGINWIDTH and MARGINHEIGHT of 0 in the <BODY> tag of the HTML file(s) to be loaded into the frame in question. These will not be recognized by Netscape 3 or earlier, though, for which there is a minimum margin of one pixel that cannot be avoided in frames.

Once again, the effects of these attributes are best demonstrated by playing around with them yourself. Always keep in mind which browsers will support each feature you use. Never use an attribute that may exclude part of your target audience.

Navigation

Now that you know how to make frames, it’s time to learn how to use them. This section will teach you how frames affect the way the links on your page work. After that, we will use what we have learned so far to design a Website that uses the well-known "menu bar" layout.

Targeted Links

Before frames, the only thing a Web author had to worry about when they created a hypertext link was the location of the document to be loaded. With frames, a new concern is introduced. Which frame should the document be loaded into?

Anyone with even a passing familiarity with HTML should know that you create a hypertext link using the anchor tag, <A>, with the HREF attribute.

<A HREF="newdoc.html">...</A> 

By default, newdoc.html will be loaded into the frame in which the link was clicked. In some cases, this is exactly what you want. But what if you created a site with two frames — one that contained a menu of documents that can be loaded into the other? In this case, you’d want the links in the menu frame to target the main frame.

The first step to accomplish this is to give your frames names. As described in the previous section, you do this with the NAME attribute of the <FRAME> tag. In our example, we would name our frames menu and main as shown here:

<FRAMESET COLS="75,*" FRAMEBORDER=0>     
<FRAME SRC="ourmenu.html" NAME="menu">    
<FRAME SRC="introduction.html" NAME="main">    
</FRAMESET>

Then, to make all links in the menu frame target our main frame, we must use the TARGET attribute of the <BASE> tag in the header of ourmenu.html, which is the file loaded in our menu frame.

<HTML>     
<HEAD>    
<BASE TARGET="main">    
</HEAD>    
<BODY>    
...

"Okay, this is all well and good," you say. "But what if I want different links in a single file to target different frames?" No problem! The <A> tag also supports a TARGET attribute, which overrides any target you may have specified using the <BASE> tag.

<A HREF="newdoc.html" TARGET="main">...</A> 

Using this, you could actually just forget about the <BASE> tag and just put TARGETs on all of your links, but unless there is no clear default target, you’ll usually save on the size of your file by setting it using the <BASE> tag.

Special Targets

As you don’t always want a link to load into one of your frames, there are several special targets that you can use. These may be used with either the <BASE> or <A HREF> tags, and must be typed exactly as they appear here, as they are case sensitive.

TARGET="_self"

Loads the link into the same frame as the link itself. This is the default behavior, and works as if the TARGET attribute were not specified at all.

TARGET="_top"

Wipes out all the frames in your window and then loads the new document into the window. Typically, you would use this whenever you provided a link leading to another site. If you didn’t, the other site would be loaded into your frames, leading to an ugly and sometimes unusable screen layout. Unless you have a special reason not to, always use this when providing links outside your site. There’s nothing more annoying for a user than being stuck in someone’s frames.

TARGET="_parent"

Loads the link into the parent of the current frame. Simply speaking, it wipes out the frameset enclosing the frame containing the link, and loads the target document in its place. The distinction between _parent and _top arises in the case of nested framesets, where you might want to load the link into the next step up in the nesting order without wiping out any "outer" frameset(s). In a simple, non-nested frameset, _parent and _top do the same thing.

TARGET="_blank"

Opens a new browser window and loads the target document into it, leaving the current frameset untouched. In some situations, this is preferable to using _top when providing a link to someone else’s site.

A Frame-Based Site

Now that we’ve covered all the basic skills that are required to use frames, let’s combine everything we’ve learned into a concrete example. As anyone who’s surfed the Web much in the past few years has doubtless noticed, one of the most popular site layouts around uses a menu bar down the left-hand side of the page. A popular twist is to put this menu bar within a frame, so that the main content of the site can be scrolled up and down without the user ever losing sight of the menu.

As with any frame-based site, we begin by setting up our frameset. We will call our frameset file index.html, assuming it will be the first page loaded when someone is entering our site. As with any frameset file, it will not contain a <BODY> tag, but instead will use <FRAMESET>, <FRAME>, and <NOFRAMES> tags to define the layout.

<HTML>      
<HEAD>      
<TITLE> Welcome to my Web site! </TITLE>      
</HEAD>      
     
<FRAMESET FRAMEBORDER=0 COLS="150,*">      
<FRAME NAME="menu" NORESIZE SRC="mainmenu.html">      
<FRAME NAME="main" SRC="welcome.html">      
</FRAMESET>      
     
<NOFRAMES>      
<H1>Welcome!</H1> <P>This site was designed to use frames to      
provide a menu bar to ease navigation; however, your browser      
does not support frames. Click <AHREF="welcome.html">here</A> to go      
to the main page of our site, where you can use the alternative      
links we have provided to get around the site.      
</NOFRAMES>      
     
</HTML>

Notice several things about this example. We have used FRAMEBORDER=0 in the <FRAMESET> tag to hide the 3D borders that appear between the frames by default. In many cases, this makes a frame-based layout more attractive by making it look more seamless.

Next, we have used the NAME attribute of the <FRAME> tag to assign an appropriate name to each of our frames. This will help us later on when we’ll need to define links between our frames.

Also notice the use of the NORESIZE attribute in our first <FRAME> tag. This prevents the user from altering the width of the menu bar, and keeps our site’s layout the way we intended it. We do not need to specify NORESIZE for the main frame, because this happens automatically when we disable resizing for the menu frame. We have two frames. Obviously, if we’re not allowed to resize one, we’re not going to be able to resize the other, as this would mean resizing the first one to fill the window properly.

Finally, we’ve used the <NOFRAMES> tag to provide an alternate welcome message for users whose browsers do not support frames. As we don’t want to have to create an entirely different version of our site for frames-incapable browsers, we simply provide a link to the same file we would normally load into our main frame. We can then provide a discreet set of links to get around our site within the main pages.

Next, we need to design our menu. As set in the frameset, our main menu will be contained in the mainmenu.html file. This will be an HTML file like any other, except that we will not need a <TITLE> tag, because frames don’t have title bars in which to display their title.

<HTML>      
<HEAD>      
<BASE TARGET="main">      
</HEAD>      
<BODY BGCOLOR="DarkSlateBlue" BACKGROUND="menuback.gif"      
TEXT="white" LINK="LightSkyBlue" ALINK="Orange" VLINK="#FF9900">      
<BASEFONT SIZE="2" FACE="Arial, Helvetica, sans-serif" SIZE="-1">      
     
<H3>Main Menu</H3>      
<HR NOSHADE>      
<A HREF="welcome.html">Welcome</A>      
<P><A HREF="products.html">Products</A>      
<P><A HREF="order.html">Order</A>      
<P><A HREF="support.html">Support</A>      
<P><A HREF="info.html">Info</A>      
<HR NOSHADE>      
     
</BODY>      
</HTML>

The main thing to notice here is the <BASE> tag, which we’ve used to specify the default target for links in this file. Quite simply, this makes all the links in our menu load their target files into the main frame.

All that’s left is to create the main pages of our site. These will be written exactly as if there were no frames in our site at all. There is no need to use the <BASE> tag, because it makes sense that, unless we specify otherwise by using the TARGET attribute in our <A> tag, we want the links in our main pages to load into our main frame. Remember that we must put a discreet set of links matching those in our menu frame somewhere, for those users whose browsers do not support frames.

I’ve provided the basics of what this site would look like. Use the following links to view it. When you’re done, close the window to return here. Feel free to use this code in your own site if you like.

See it in Action | View the Code

Advanced Issues

For those of you who are especially curious, or for those who already have a good knowledge of frames, but would like to learn a fancy trick or two, this section covers two advanced frame techniques. The first covers probably the most frequently-asked question in the world of frame design: "How do I make one link change two frames?" The second is a clever trick that allows you to avoid writing many little HTML files to fill in simple and repetitive frames.

Both of these techniques require a certain understanding of JavaScript, but I’ll explain everything from the ground up. Anyone with a basic understanding of programming concepts should have no problem following along.

Multi-Frame Links

So, you’ve been scribbling rectangular boxes on Post-It notes all day, and you’ve finally come up with the ultimate layout for your new site. You sift through the crumpled yellow squares covering your desk to find your mouse, and pop open your editor. As you stare at the screen, you come to a sudden, horrible realization. For your layout to work, you’re going to need to make one link change the contents of two frames.

Are you sunk? Of course not! Enter JavaScript. Using this simple language, we will change our link so that instead of loading a file into a frame, it will trigger a little piece of JavaScript that we have set aside, having defined it in the heading of our file. This piece of JavaScript is called a function, and will do the tricky job of changing several frames at once. More on this in a moment.

Before we go any further, let me say that the technique described here will work for all Netscape browsers, as well as for Internet Explorer 4.0. Users of Internet Explorer 3.0 will be unable to properly access your site if you use this technique, so be sure that you weigh your options to decide whether multi-frame links are really worth it.

In case you’re new to JavaScript, let me describe how this clever language works. JavaScript is what is commonly referred to as an object-oriented programming language. In simple terms, this means it thinks of everything in terms of objects. Your Web browser is an object, the browser window is an object, the images in your Web pages are objects, and your frames are objects! The nice thing about objects is that you can change things about them. Things that you can change in a particular object are known as that object’s properties.

One of the properties of the object representing the browser window (the window object) is the document. As it turns out, the document is an object as well (didn’t I tell you everything was an object?). One of the properties of the document object is its location. This location is the URL of the document currently displayed by the window.

"What’s this have to do with my problem with multi-frame links?" you ask. Well, as I’ve already said, you can change the properties of objects. So what happens if you change the location property of the document of one of your frames? Well, the frame loads the new URL, naturally. And in JavaScript, there’s nothing to stop you from changing as many properties of as many objects as you wish!

Let me start by showing you the JavaScript involved in changing the contents of a single frame.

parent.frames["name"].document.location = "newdoc.html";

Where name is the name of the frame you want to change, and newdoc.html is the filename or URL of the new document to be loaded into that frame. This is the JavaScript way of saying:

"In the parent window, in the frame called "name", change the document’s location to "newdoc.html"."

Okay, so you now have a really fancy way of doing what you already know how to do. How do you change the location of more than one frame? Well, you just repeat that line of JavaScript for each frame you want to change.

parent.frames["frame1"].document.location = "newdoc1.html";       
     
parent.frames["frame2"].document.location = "newdoc2.html";      
     
...

So, where does all this fancy JavaScript stuff go, exactly? Well, as I mentioned, each of your links is going to trigger a little piece of JavaScript called a function. You define functions in the heading of your HTML file, inside a <SCRIPT> tag.

<HTML>       
<HEAD>      
...      
<SCRIPT LANGUAGE="JavaScript">      
<!-- Hide from older browsers      
function speciallink() {      
parent.frames["frame1"].document.location = "newdoc1.html";      
parent.frames["frame2"].document.location = "newdoc2.html";      
}      
     
// -->      
</SCRIPT>      
</HEAD>      
...

In the above example, we’ve defined a JavaScript function called speciallink(), which changes the contents of two frames. All that’s left now is to trigger that function when the user clicks on the correct link.

All this requires is a fancy form of the <A HREF> tag we all know and love:

<A HREF="javascript:speciallink()">...</A> 

We call this a JavaScript link. This simply tells the browser that when the link is clicked, it is to run the JavaScript function called speciallink(), which, as you know, is defined in the heading of the file.

It is important not to use the TARGET attribute of the <A> tag when using this technique. Remember, you have multiple "target" frames in this case, and they are already being specified in the JavaScript function. If you were to use the TARGET attribute, your browser would look for the JavaScript function in the TARGET frame you specify. In some special instances, you might want to do this, but for our purposes this is something to be avoided. For the same reason, be sure not to use the <BASE TARGET=...> method of specifying the default target frame in a document with JavaScript links.

So to sum it up, for each link that you want to change more than one frame, create a JavaScript function that makes the required changes. Then, point to that function with a JavaScript link.

As an example, consider the sample frame-based site we built in the previous section. At the top of each page, we had a title in large print which corresponded to the section of the site you were in (Products, Ordering, Customer Support, etc.). What if we wanted to place that title in its own frame at the top of the page, so that when the user scrolled down, it would remain visible? Whenever the user clicked on a link on the menu, we would have to change both the title and the main page.

This is easy to do with the new techniques we’ve learned. Here is our modified example:

See it in Action | View the Code

If you’re going to use this technique on a large scale, you may want to invest a little time into learning more about JavaScript. Imagine, for example, that your site had five main sections, each with multiple subsections, and you wanted to be able to handle multi-frame links not only in your menu, but also in the main pages. You would have to write an incredible number of JavaScript functions, and repeat them in the heading of almost every HTML file in your site.

With a good knowledge of JavaScript, it’s possible to do things like sharing a single, multi-purpose function between all your frames and HTML files. Thus, you could cut down greatly on the amount of code required for implementing this technique across a large site. The simple technique I’ve demonstrated here will work perfectly on a small, personal site though.

Scripted Frames

Often when you’re writing a frames-based site, you want to use a frame to display something simple, like a title or a definition, and you find yourself writing scores of little HTML files to load into this frame.

Let’s take the practical (if mundane) example of a frame for which we are able to choose the text and background colours. In one frame, we’ll have links for each text/background colour combination. In the other, we’ll display the result of the user’s choice. Now, while we only need one HTML file for the frame containing the links, we’ll need a different HTML file for each colour combination we want to be able to display in the second frame. Each of these files will be small, and will look like this:

<HTML>        
<BODY BGCOLOR="bgcolor" TEXT="textcolor">        
Can you read this?        
</BODY>        
</HTML>

Pretty boring, huh? The worst part of this is not that you’ll need to type these one by one, but that the user’s browser will have to download each one of them individually! What if I told you there was no need to write each of those little files? What if I told you that you can change the contents of a frame without having to load a new HTML file?

In the section above, I taught you a little about JavaScript objects, properties, and functions. Well it so happens that some JavaScript objects, besides having properties you can change, also have built-in functions that you can use to do special things to them. These built-in functions are called methods.

As you’ll recall, the document object represents the HTML file loaded into a given frame. We’ve already seen that the document object has a property called location that you can use to load a new file into it. As it turns out, the document object also has a method called write(), which allows you to modify the contents of the frame directly. Along with write(), there are also two other methods we will need called open() and close(). open() clears the contents of the document and prepares it to be written into using the write() method. close() tells your browser that you’re done writing into the document and it can now display the changes you’ve made.

So instead of loading a new file, we could change the contents of our sample frame like this:

parent.frames["sample"].document.open();        
parent.frames["sample"].document.write('<HTML>');        
parent.frames["sample"].document.write('<BODY BGCOLOR="bgcolor"        
TEXT="textcolor">');        
parent.frames["sample"].document.write('Can you read this?');        
parent.frames["sample"].document.write('</BODY>');        
parent.frames["sample"].document.write('</HTML>');        
parent.frames["sample"].document.close();

Notice how the text we want to write goes between the parentheses in write(), and is enclosed in single quotes ('). The choice of single quotes was made so that they wouldn’t interfere with any double quotes (") in the HTML code being written.

As a shortcut, we’ll create a variable to store the location of the document we’re writing to. Think of this as a JavaScript "bookmark", that we can use to refer to parent.frames["sample"].document with a convenient name. We use the keyword var to create a new variable and assign it a value.

var sampledoc = parent.frames["sample"].document;        
sampledoc.open();        
sampledoc.write('<HTML>');        
sampledoc.write('<BODY BGCOLOR="bgcolor" TEXT="textcolor">');        
sampledoc.write('Can you read this?');        
sampledoc.write('</BODY>');        
sampledoc.write('</HTML>');        
sampledoc.close();

Now, for the big trick. What if we also used variables for the text bgcolor and textcolor? We could then change the value of these variables to whatever we wanted, and reuse this whole chunk of code to write our sample frame each time!

var bgcolor = 'black';        
var textcolor = 'lightsteelblue';        
var sampledoc = parent.frames["sample"].document;        
       
sampledoc.open();        
sampledoc.write('<HTML>');        
sampledoc.write('<BODY BGCOLOR="' +        
bgcolor + '" TEXT="' + textcolor + '">');        
sampledoc.write('Can you read this?');        
sampledoc.write('</B></FONT>');        
sampledoc.write('</BODY>');        
sampledoc.write('</HTML>');        
sampledoc.close();

Notice how we use the ‘+‘ operator to stick pieces of text together with the contents of our two variables.

To complete the picture, we insert this whole chunk of code into a JavaScript function. The function lets us trigger this writing operation whenever the user clicks on a link. It also does one other important thing. It lets us specify the values of our two color variables when we trigger the function! We do this by inserting between the parentheses in our function name the names of the variables we’d like to specify the values of when the function is triggered, separated by colons.

Our completed function will look like this:

function chgcolor(bgcolor,textcolor) {        
       
var sampledoc = parent.frames["sample"].document;        
       
sampledoc.open();        
sampledoc.write('<HTML>');        
sampledoc.write('<BODY BGCOLOR="' +        
bgcolor + '" TEXT="' + textcolor + '">');        
sampledoc.write('Can you read this?');        
sampledoc.write('</B></FONT>');        
sampledoc.write('</BODY>');        
sampledoc.write('</HTML>');        
sampledoc.close();        
       
}

A link to trigger this function with a Black background and LightSteelBlue text would look like this:

<A HREF="javascript:chgcolor('Black','LightSteelBlue');">...</A> 

And that’s it! You have now drastically cut the amount of downloading the user’s browser will have to do, as well as the amount of typing you’ll have to do (depending on how many colour combinations you plan to offer).

See it in Action | View the Code

In Summary

In this article I’ve endeavored to present a fairly complete picture of the techniques involved in building Websites using frames. Not only did I cover the basics in terms that, hopefully, were accessible to anyone with a rudimentary knowledge of Web design and general programming, but I also covered some more advanced topics that would prove useful to the more experienced Web developer.

For more information on frames, try:

Free Chapter! HTML5 & CSS3 for the Real World

Get a free chapter of SitePoint's new book, the second edition of our popular HTML5 & CSS3 for the Real World and receive updates on our latest offers.

No Reader comments