Designing with Frames – an Introduction

Share this article

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.

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>

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)!

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.

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:

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).

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:

Frequently Asked Questions about HTML Frames

What are HTML frames and why are they used?

HTML frames are a way to divide the browser window into multiple sections where each section can load a separate HTML document. They are used to display more than one HTML document in the same browser window. For example, you can use frames to keep a navigation menu visible while the rest of the page scrolls.

Are HTML frames still relevant today?

While HTML frames were popular in the early days of web development, they are now considered outdated. Most modern websites use CSS and JavaScript for layout and navigation, which offer more flexibility and compatibility. However, understanding frames can still be useful for maintaining older websites.

What are the disadvantages of using HTML frames?

There are several disadvantages to using frames. They can make a website difficult to navigate, as not all browsers support frames. They can also cause problems with bookmarking and printing. Additionally, frames can make it harder for search engines to index your site, which can affect your site’s SEO.

How do I create an HTML frame?

To create an HTML frame, you need to use the

tag to define the layout of the frames, and the tag to specify the content of each frame. For example, to create a horizontal split with two frames, you would use the following code:




Can I nest frames within frames?

Yes, you can nest frames within frames by using the

tag inside another tag. This allows you to create complex layouts with multiple levels of frames. However, keep in mind that nested frames can make your site more difficult to navigate and may not be supported by all browsers.

How do I target a link to a specific frame?

To target a link to a specific frame, you need to use the “target” attribute in your tag. The value of the “target” attribute should be the name of the frame you want to target. For example, if you have a frame named “menu”, you can target a link to this frame like this:

Link

What is the difference between frames and iframes?

While both frames and iframes allow you to display multiple HTML documents in the same browser window, there are some key differences. Frames divide the entire browser window into sections, each with its own scroll bar. Iframes, on the other hand, are embedded within a single HTML document and have their own scroll bar. Iframes are more widely supported and are generally preferred over frames.

How do I style frames with CSS?

Styling frames with CSS can be a bit tricky, as not all CSS properties apply to frames. However, you can style the content within each frame by linking to a CSS file within the HTML document loaded in the frame. You can also use inline styles within the tag, but this is generally not recommended.

Can I use JavaScript with frames?

Yes, you can use JavaScript with frames. However, keep in mind that each frame is a separate HTML document, so any JavaScript code needs to be included in the HTML document loaded in the frame. Also, due to security restrictions, JavaScript can only access frames that are from the same domain.

What are some alternatives to frames?

There are several alternatives to frames that offer more flexibility and compatibility. These include using CSS for layout, using JavaScript for dynamic content, and using AJAX for loading content without refreshing the page. Additionally, you can use iframes, which are similar to frames but are more widely supported and easier to use.

Kevin YankKevin Yank
View Author

Kevin Yank is an accomplished web developer, speaker, trainer and author of Build Your Own Database Driven Website Using PHP & MySQL and Co-Author of Simply JavaScript and Everything You Know About CSS is Wrong! Kevin loves to share his wealth of knowledge and it didn't stop at books, he's also the course instructor to 3 online courses in web development. Currently Kevin is the Director of Front End Engineering at Culture Amp.

Share this article
Read Next
Creating Fluid Typography with the CSS clamp() Function
Creating Fluid Typography with the CSS clamp() Function
Daine Mawer
Comparing Full Stack and Headless CMS Platforms
Comparing Full Stack and Headless CMS Platforms
Vultr
7 Easy Ways to Make a Magento 2 Website Faster
7 Easy Ways to Make a Magento 2 Website Faster
Konstantin Gerasimov
Powerful React Form Builders to Consider in 2024
Powerful React Form Builders to Consider in 2024
Femi Akinyemi
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Ralph Mason
Sending Email Using Node.js
Sending Email Using Node.js
Craig Buckler
Creating a Navbar in React
Creating a Navbar in React
Vidura Senevirathne
A Complete Guide to CSS Logical Properties, with Cheat Sheet
A Complete Guide to CSS Logical Properties, with Cheat Sheet
Ralph Mason
Using JSON Web Tokens with Node.js
Using JSON Web Tokens with Node.js
Lakindu Hewawasam
How to Build a Simple Web Server with Node.js
How to Build a Simple Web Server with Node.js
Chameera Dulanga
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Beloslava Petrova
Crafting Interactive Scatter Plots with Plotly
Crafting Interactive Scatter Plots with Plotly
Binara Prabhanga
GenAI: How to Reduce Cost with Prompt Compression Techniques
GenAI: How to Reduce Cost with Prompt Compression Techniques
Suvoraj Biswas
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
Aurelio De RosaMaria Antonietta Perna
Quick Tip: How to Align Column Rows with CSS Subgrid
Quick Tip: How to Align Column Rows with CSS Subgrid
Ralph Mason
15 Top Web Design Tools & Resources To Try in 2024
15 Top Web Design Tools & Resources To Try in 2024
SitePoint Sponsors
7 Simple Rules for Better Data Visualization
7 Simple Rules for Better Data Visualization
Mariia Merkulova
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
SitePoint Team
Best Programming Language for AI
Best Programming Language for AI
Lucero del Alba
Quick Tip: How to Add Gradient Effects and Patterns to Text
Quick Tip: How to Add Gradient Effects and Patterns to Text
Ralph Mason
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Vultr
How to Optimize Website Content for Featured Snippets
How to Optimize Website Content for Featured Snippets
Dipen Visavadiya
Psychology and UX: Decoding the Science Behind User Clicks
Psychology and UX: Decoding the Science Behind User Clicks
Tanya Kumari
Build a Full-stack App with Node.js and htmx
Build a Full-stack App with Node.js and htmx
James Hibbard
Digital Transformation with AI: The Benefits and Challenges
Digital Transformation with AI: The Benefits and Challenges
Priyanka Prajapat
Quick Tip: Creating a Date Picker in React
Quick Tip: Creating a Date Picker in React
Dianne Pena
How to Create Interactive Animations Using React Spring
How to Create Interactive Animations Using React Spring
Yemi Ojedapo
10 Reasons to Love Google Docs
10 Reasons to Love Google Docs
Joshua KrausZain Zaidi
How to Use Magento 2 for International Ecommerce Success
How to Use Magento 2 for International Ecommerce Success
Mitul Patel
5 Exciting New JavaScript Features in 2024
5 Exciting New JavaScript Features in 2024
Olivia GibsonDarren Jones
Tools and Strategies for Efficient Web Project Management
Tools and Strategies for Efficient Web Project Management
Juliet Ofoegbu
Choosing the Best WordPress CRM Plugin for Your Business
Choosing the Best WordPress CRM Plugin for Your Business
Neve Wilkinson
ChatGPT Plugins for Marketing Success
ChatGPT Plugins for Marketing Success
Neil Jordan
Managing Static Files in Django: A Comprehensive Guide
Managing Static Files in Django: A Comprehensive Guide
Kabaki Antony
The Ultimate Guide to Choosing the Best React Website Builder
The Ultimate Guide to Choosing the Best React Website Builder
Dianne Pena
Exploring the Creative Power of CSS Filters and Blending
Exploring the Creative Power of CSS Filters and Blending
Joan Ayebola
How to Use WebSockets in Node.js to Create Real-time Apps
How to Use WebSockets in Node.js to Create Real-time Apps
Craig Buckler
Best Node.js Framework Choices for Modern App Development
Best Node.js Framework Choices for Modern App Development
Dianne Pena
SaaS Boilerplates: What They Are, And 10 of the Best
SaaS Boilerplates: What They Are, And 10 of the Best
Zain Zaidi
Understanding Cookies and Sessions in React
Understanding Cookies and Sessions in React
Blessing Ene Anyebe
Enhanced Internationalization (i18n) in Next.js 14
Enhanced Internationalization (i18n) in Next.js 14
Emmanuel Onyeyaforo
Essential React Native Performance Tips and Tricks
Essential React Native Performance Tips and Tricks
Shaik Mukthahar
How to Use Server-sent Events in Node.js
How to Use Server-sent Events in Node.js
Craig Buckler
Five Simple Ways to Boost a WooCommerce Site’s Performance
Five Simple Ways to Boost a WooCommerce Site’s Performance
Palash Ghosh
Elevate Your Online Store with Top WooCommerce Plugins
Elevate Your Online Store with Top WooCommerce Plugins
Dianne Pena
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Dianne Pena
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
Vultr
Enhance Your React Apps with ShadCn Utilities and Components
Enhance Your React Apps with ShadCn Utilities and Components
David Jaja
10 Best Create React App Alternatives for Different Use Cases
10 Best Create React App Alternatives for Different Use Cases
Zain Zaidi
Control Lazy Load, Infinite Scroll and Animations in React
Control Lazy Load, Infinite Scroll and Animations in React
Blessing Ene Anyebe
Building a Research Assistant Tool with AI and JavaScript
Building a Research Assistant Tool with AI and JavaScript
Mahmud Adeleye
Understanding React useEffect
Understanding React useEffect
Dianne Pena
Web Design Trends to Watch in 2024
Web Design Trends to Watch in 2024
Juliet Ofoegbu
Building a 3D Card Flip Animation with CSS Houdini
Building a 3D Card Flip Animation with CSS Houdini
Fred Zugs
How to Use ChatGPT in an Unavailable Country
How to Use ChatGPT in an Unavailable Country
Dianne Pena
An Introduction to Node.js Multithreading
An Introduction to Node.js Multithreading
Craig Buckler
How to Boost WordPress Security and Protect Your SEO Ranking
How to Boost WordPress Security and Protect Your SEO Ranking
Jaya Iyer
Understanding How ChatGPT Maintains Context
Understanding How ChatGPT Maintains Context
Dianne Pena
Building Interactive Data Visualizations with D3.js and React
Building Interactive Data Visualizations with D3.js and React
Oluwabusayo Jacobs
JavaScript vs Python: Which One Should You Learn First?
JavaScript vs Python: Which One Should You Learn First?
Olivia GibsonDarren Jones
13 Best Books, Courses and Communities for Learning React
13 Best Books, Courses and Communities for Learning React
Zain Zaidi
5 jQuery.each() Function Examples
5 jQuery.each() Function Examples
Florian RapplJames Hibbard
Implementing User Authentication in React Apps with Appwrite
Implementing User Authentication in React Apps with Appwrite
Yemi Ojedapo
AI-Powered Search Engine With Milvus Vector Database on Vultr
AI-Powered Search Engine With Milvus Vector Database on Vultr
Vultr
Understanding Signals in Django
Understanding Signals in Django
Kabaki Antony
Why React Icons May Be the Only Icon Library You Need
Why React Icons May Be the Only Icon Library You Need
Zain Zaidi
View Transitions in Astro
View Transitions in Astro
Tamas Piros
Getting Started with Content Collections in Astro
Getting Started with Content Collections in Astro
Tamas Piros
What Does the Java Virtual Machine Do All Day?
What Does the Java Virtual Machine Do All Day?
Peter Kessler
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Mayank Singh
Layouts in Astro
Layouts in Astro
Tamas Piros
.NET 8: Blazor Render Modes Explained
.NET 8: Blazor Render Modes Explained
Peter De Tender
Mastering Node CSV
Mastering Node CSV
Dianne Pena
A Beginner’s Guide to SvelteKit
A Beginner’s Guide to SvelteKit
Erik KückelheimSimon Holthausen
Brighten Up Your Astro Site with KwesForms and Rive
Brighten Up Your Astro Site with KwesForms and Rive
Paul Scanlon
Which Programming Language Should I Learn First in 2024?
Which Programming Language Should I Learn First in 2024?
Joel Falconer
Managing PHP Versions with Laravel Herd
Managing PHP Versions with Laravel Herd
Dianne Pena
Accelerating the Cloud: The Final Steps
Accelerating the Cloud: The Final Steps
Dave Neary
An Alphebetized List of MIME Types
An Alphebetized List of MIME Types
Dianne Pena
The Best PHP Frameworks for 2024
The Best PHP Frameworks for 2024
Claudio Ribeiro
11 Best WordPress Themes for Developers & Designers in 2024
11 Best WordPress Themes for Developers & Designers in 2024
SitePoint Sponsors
Top 10 Best WordPress AI Plugins of 2024
Top 10 Best WordPress AI Plugins of 2024
Dianne Pena
20+ Tools for Node.js Development in 2024
20+ Tools for Node.js Development in 2024
Dianne Pena
The Best Figma Plugins to Enhance Your Design Workflow in 2024
The Best Figma Plugins to Enhance Your Design Workflow in 2024
Dianne Pena
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Christopher Collins
Build Your Own AI Tools in Python Using the OpenAI API
Build Your Own AI Tools in Python Using the OpenAI API
Zain Zaidi
The Best React Chart Libraries for Data Visualization in 2024
The Best React Chart Libraries for Data Visualization in 2024
Dianne Pena
7 Free AI Logo Generators to Get Started
7 Free AI Logo Generators to Get Started
Zain Zaidi
Turn Your Vue App into an Offline-ready Progressive Web App
Turn Your Vue App into an Offline-ready Progressive Web App
Imran Alam
Clean Architecture: Theming with Tailwind and CSS Variables
Clean Architecture: Theming with Tailwind and CSS Variables
Emmanuel Onyeyaforo
How to Analyze Large Text Datasets with LangChain and Python
How to Analyze Large Text Datasets with LangChain and Python
Matt Nikonorov
6 Techniques for Conditional Rendering in React, with Examples
6 Techniques for Conditional Rendering in React, with Examples
Yemi Ojedapo
Introducing STRICH: Barcode Scanning for Web Apps
Introducing STRICH: Barcode Scanning for Web Apps
Alex Suzuki
Using Nodemon and Watch in Node.js for Live Restarts
Using Nodemon and Watch in Node.js for Live Restarts
Craig Buckler
Task Automation and Debugging with AI-Powered Tools
Task Automation and Debugging with AI-Powered Tools
Timi Omoyeni
Quick Tip: Understanding React Tooltip
Quick Tip: Understanding React Tooltip
Dianne Pena
12 Outstanding AI Tools that Enhance Efficiency & Productivity
12 Outstanding AI Tools that Enhance Efficiency & Productivity
Ilija Sekulov
React Performance Optimization
React Performance Optimization
Blessing Ene Anyebe
Introducing Chatbots and Large Language Models (LLMs)
Introducing Chatbots and Large Language Models (LLMs)
Timi Omoyeni
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Ampere Computing
Get the freshest news and resources for developers, designers and digital creators in your inbox each week