For some reason, thousands of people learning how to write HTML make their first site using frames. I did. And I can tell you now, it’s probably not the best idea, since frames are fairly hard to, at first figure out, and second to implement; and are the source of all sorts of potential mess ups. So, my advice is, if you are a relatively new coder, stay away from frames (a better bet would be to use CSS layout or even tables). Need convincing? Read the companion piece, Frames: Good or Bad?.
Now that they’re gone, I should be left with a group of people who want to learn something new, and some people who won’t listen to good reason. Great. Let’s start.
This page was last updated on 2012-08-21
Frames are a way of displaying two or more pages at once. They are also a way of having a static navigation bar on your page at all times, with your content down the other side of the page. That’s how they’re usually used. So, when you write a frames page, the code looks very different to any of your other pages. For example:
The diagram above is what you want your page to look like. A navigation strip down the left, and your page content occupying the rest of the screen. If this was your design, to make it you would need 3 pages: the nav page, the content page, and the page that holds them both. Yep, it’s confusing.
This ’container’ page contains all the frame commands. This is the page you open, and the other two open inside this. You have full control over the layout of this page. If you want three columns for example, it’s simply a matter of adding this command into the container page, and making the third extra page.
The container page’s format is unlike any other page, as it contains no content of its own — just the frame elements.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<head><title>My First Frame Page</title>
<frameset cols="30%, 70%">
....and that’s all that goes in the whole page. You should have noticed that a container or frameset page contains no <body> section. That is because there is no text, links or anything to be affected by it.
So what’s going on here, anyway?
- This is the standard Document Type Declaration that should be atop all of your pages to tell your browser which version of HTML you’re using. This one declares the page to be one that uses framesets. There are more DOCTYPES here.
- starts off a new frame grouping, or set, into which you will be placing the frames. If you have read through the tables lessons, this can be equated to the main
tabletag — i.e. it is wrapped around all the other tags.
- is an attribute of the frameset element. It stands for COLumnS, so you cut your page up into as many columns as you want here. The values are put in as either pixel values or percentages of the screen width; with a comma between each value. Make sure the maths is correct.
- is where the inset pages are added. This SRC is the same as any other source attribute (like the <img src="..."> for example), so you just put the address of the page you want to be in that frame. Remember to include as many sources as you have columns, or you’ll be confusing your browser.
So, copy and paste that code into a new HTML file. Create two more normal HTML files, nav.html and content.html, and save them with the first file. When you open it, you will have something like this example frameset.
Adding rows to the layout
Great, you want me to make it even more complicated. Thanks. Alright, but I did warn you. Here’s what we’re aiming for:
Man, I bet my brilliant Home Alone references are far too clever for everyone... Ahem, anyway that’s a messy one. Here’s the code.
<frameset cols="25%, 75%">
<frameset rows="50%, 50%">
<frameset rows="50%, 50%">
Let me be the first to apologise for how fiddly this whole system is. Hey, I didn’t make it up. Anyway, I better help you guys figure this one out.
What’s happening is that you’re setting up your layout much like the last example — two columns at 25 and 75 percent respectively. Then you put two more
framesets into this existing frameset — each controlling their column. The first one you put in will be 25 wide in this case, and the second will be 75. Then these secondary framesets split each side into rows. Notice that you’re working vertically, i.e. ’A’ and then ’and’ come before ’2’. Here, have another example:
<frameset cols="25%, 75%">
<frameset rows="50%, 50%">
<frameset rows="33%, 33%, 33%">
Ack! To be honest, this is far too many frames to use in one layout — 2 or 3 should be your maximum, and 4 is already too much. It’s all about mess-up limitation. Also, check out how a column can be split into three rows by setting them all at 33%. Don’t worry about the extra percent, your browser will magic it away without any extra work by you.
sourcetip: if you couldn’t be bothered working out the computations, just put a star ( * ) as the height/width of one of your frames. As long as all the others are put in your browser will give all the space left to this frame.
Linking between them
Now you have your layout done, and you have pages open in each of your frames. As you have probably noticed in your layout already, at the moment a link will only open in the frame it was clicked in. That’s a bit useless if you’re using frames as navigation. So you need to set it up so that once a link is pressed in one frame, another frame receives this information.
For this example, we’ll be calling back our basic frame layout:
The trick is to
name your frames, so you can specify in the link which frame you want the page to open in. So here’s the code for that layout, with named frames:
<frame src="nav.html" name="nav">
<frame src="content.html" name="content">
Of course, you can call them whatever you want, but keep it short and simple, because you may need to use the names quite a lot. Now, you add an attribute to your links called
target, in which you specify the name of the frame you want to open the new page in. So, put this link into nav.html somewhere.
<a href="page2.html" target="content">
Understand that? Just match the
target with the
name of the chosen frame.
If you want to click on a link and have it open free from any frames at all, to go over the whole page, use
target="_top". Remember while using this however, that your frame layout will be left behind, thereby losing any links or content you had in them. This is useful however if you want to open a new frameset. Also, the beginning underscore ( _ ) has to be there, to tell the browser that it’s not the name of a frame, and ’top’ has to be in small letters.
Similiarily, if you want to open a new page in a completely new, pop-up window, use
target="_blank". This will keep your original page open in the background so your reader can return to it after they’ve perused the link. This is very useful for linking to other websites that aren’t yours, because you don’t immediately lose the visitor, they’ll be back in a few minutes to continue through your site.
sourcetip: Instead of having to add a target to every link in your navigation frame, simply add
<base target="name"> to the
<head> part of the navigation page, where
name is the name of the frame you’re targeting. This will make it the default target for all links in the frame.
What about the guys with rubbish browsers?
This is becoming a smaller problem by the day, but there are still people out there who haven’t got themselves a decent browser. Anything under version 3 browsers can’t do frames. A more pressing problem is that readers with disabilities that use special software to read webpages will often not be able to access framed pages. So we have a problem — these people will get a blank screen when they go to your page, with no hope of reading any of your no-doubt excellent musings.
Your only options are not to use frames; make two versions of the page, one frame-enabled and the other not (really not worth the effort); or use the rather marvellous
<noframes> tag. With this you can offer something to compensate for the lack of anything interesting to read, by leaving a message for these poor unfortunates. The format is thus:
It’s not the dark ages anymore, people!
With this, your message will be the only thing these people will see. You actually could put your whole page into this section of your page (just put in the
<body> tags and you’re away), but that’s sort of defeating the purpose. The best utilisation of this feature is to point users towards a browser updates page (you can use ours), and encourage them to download the best browser out there. Offer a description of your site and a link to your main content page as part of this text, as much for potential readers as search engines.
One more thing to note: make sure the
noframes section is below your framesets, because old versions of Netscape will just show that instead of your proper page, even if it capable of the full deal.
And that is that.