The HTML frameset tag, with an example, and what to use instead
<frameset> split a browser window into several independent documents, each in its own <frame>. It was common in the late 1990s for sites with a fixed menu on the left and content on the right. It is obsolete in HTML5, but you still meet it in old intranet applications and in documentation generators, so it helps to know how it works and how to replace it.
How a frameset page is built
A frameset document has no <body>. In its place, <frameset> divides the window into rows or columns, and each <frame> loads a separate HTML file. Framesets can nest to create a grid.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<meta charset="utf-8">
<title>Manual</title>
</head>
<frameset rows="70,*">
<frame src="header.html" name="top" scrolling="no" noresize>
<frameset cols="220,*">
<frame src="menu.html" name="menu">
<frame src="welcome.html" name="content">
</frameset>
<noframes>
<body>
<p>This manual uses frames. <a href="menu.html">Open the table of contents</a>.</p>
</body>
</noframes>
</frameset>
</html>
The menu file opens its links in the right-hand frame by naming it in target:
<!-- menu.html -->
<ul>
<li><a href="install.html" target="content">Installation</a></li>
<li><a href="usage.html" target="content">Usage</a></li>
<li><a href="faq.html" target="content">FAQ</a></li>
</ul>
Save the four files in one folder and open the frameset file: browsers still render framesets for compatibility, even though the element is no longer valid HTML.
Attributes
| Element | Attribute | Meaning |
|---|---|---|
frameset | rows, cols | Comma-separated sizes: pixels (200), percentages (25%) or relative shares (*, 2*). |
frame | src | The document shown in the frame. |
frame | name | The name used by target on links and forms. |
frame | noresize | Stops the user from dragging the border. |
frame | scrolling | yes, no or auto. |
frame | frameborder, marginwidth, marginheight | Presentation, nowadays done with CSS. |
Special target values work across frames: _top replaces the whole frameset (use it for links leaving the site), _parent the parent frameset, _self the current frame, _blank a new window or tab.
Why frames were abandoned
- One URL for many states. The address bar shows the frameset URL whatever is in the content frame, so bookmarks and shared links lead to the start page.
- Search engines index the individual frame documents, so visitors arrive on a content page without its menu.
- Accessibility. Screen readers must navigate between separate documents; the back button behaves unpredictably.
- Printing and small screens work badly with fixed divisions of the window.
The HTML Living Standard lists frame, frameset and noframes as obsolete features that authors must not use.
Replacement 1: one page with a CSS grid layout
The most common reason for frames, a header and a fixed menu, is a layout problem, and CSS solves it in a single document:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Manual: Installation</title>
<style>
body {
margin: 0;
display: grid;
grid-template-columns: 220px 1fr;
grid-template-rows: 70px 1fr;
grid-template-areas: "head head" "menu main";
height: 100vh;
}
header { grid-area: head; padding: 1rem; border-bottom: 1px solid #ccc; }
nav { grid-area: menu; overflow-y: auto; border-right: 1px solid #ccc; }
main { grid-area: main; overflow-y: auto; padding: 1rem 2rem; }
@media (max-width: 640px) {
body { display: block; height: auto; }
nav { border-right: 0; border-bottom: 1px solid #ccc; }
}
</style>
</head>
<body>
<header>Manual</header>
<nav>
<ul>
<li><a href="install.html" aria-current="page">Installation</a></li>
<li><a href="usage.html">Usage</a></li>
<li><a href="faq.html">FAQ</a></li>
</ul>
</nav>
<main>
<h1>Installation</h1>
<p>…</p>
</main>
</body>
</html>
Each page has its own URL and title, and the menu and content scroll independently as they did in frames. On narrow screens the layout falls back to a single column.
Replacement 2: share the menu without copying it
Frames were also used to avoid repeating the menu in every file. Server-side templates do that properly:
- in ASP.NET Web Forms, a master page holds the header and menu, and each content page fills a
ContentPlaceHolder; - in ASP.NET MVC and Core, a Razor layout (
_Layout.cshtml) does the same; - a static site generator, or server-side includes on simpler hosting, can assemble pages at build or request time.
The menu control described in How to use the ASP.NET Menu control is typically placed in a master page for this reason.
Replacement 3: iframe, for embedding
<iframe> is not obsolete: it embeds one document inside another, such as a map, a video player or a payment form from another origin. Use it for embedding, not for site layout, and add title for screen readers. For untrusted content, the sandbox attribute restricts what the embedded page may do.
<iframe src="https://example.org/widget" title="Opening hours widget"
width="400" height="300" loading="lazy" sandbox="allow-scripts"></iframe>
Migrating an old frameset site
- List the frame documents and identify the shared parts (header, menu).
- Move the shared parts into a layout (master page, template or include).
- Turn each content frame document into a full page using that layout.
- Redirect the old frameset URL to the new start page with a permanent redirect.
- Remove
target="content"from links; they now open in the same window.
Frames inside ASP.NET applications
Older intranet applications sometimes load an .aspx page in each frame. Two behaviours surprise developers when maintaining them. First, Response.Redirect only changes the frame that made the request; to leave the frameset, the response has to run script such as window.top.location = "…", which is also what a login page must do when a session expires inside a frame. Second, modern browsers block third-party cookies in frames more strictly, so a frame showing pages from another domain may lose its session. Both are good reasons to migrate to a single-document layout as described above.
References
- MDN: <frameset>, <frame>, <iframe>
- WHATWG HTML Living Standard: Obsolete features
- MDN: CSS grid layout
- Microsoft Learn: ASP.NET master pages