Skip to main content
HTML Validation

The “frameset” element is obsolete. Use the “iframe” element and CSS instead, or use server-side includes.

About This HTML Issue

The <frameset> element is obsolete, so a page split into frames has to become a normal page with a <body>, using CSS for the layout and <iframe> or server-side includes for the shared parts.

A frameset document has a <frameset> where the <body> would go, and each <frame> inside it loads a separate HTML file into one pane of the window. The HTML standard lists <frameset>, <frame> and <noframes> as obsolete. Browsers still render framesets so old sites keep working, but the validator reports the <frameset> once and then each <frame> and <noframes> with a message of its own. The rows and cols attributes go away with the element and aren't reported separately.

Frames cause trouble beyond validation. The address bar keeps showing the frameset's URL whatever is loaded inside it, so a visitor can't bookmark or share a specific page, and search engines can send people straight to a framed page without the navigation that was meant to surround it.

The fix depends on what the frames were for. When they hold shared navigation, the usual answer is one complete page per URL, with the navigation pulled in on the server through an include, a template or a static site generator. When a pane really has to load other documents, an <iframe> inside a regular <body> does that job, sized with CSS and given a title so screen readers can announce it. A frameset with a single frame that fills the window, such as rows="100%,*", is often the "masked forwarding" a domain registrar sets up to show another site under a different domain. In that case, replace it with an HTTP 301 redirect to the real site.

Invalid example

A manual with a table of contents on the left and the chapter on the right:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Product manual</title>
  </head>
  <frameset cols="25%,75%">
    <frame src="contents.html">
    <frame src="chapter-1.html">
  </frameset>
</html>

Valid example

The table of contents moves into the page, and an <iframe> loads each chapter that its links target:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Product manual</title>
    <link rel="stylesheet" href="manual.css">
  </head>
  <body>
    <nav>
      <ul>
        <li><a href="chapter-1.html" target="chapter">Chapter 1</a></li>
        <li><a href="chapter-2.html" target="chapter">Chapter 2</a></li>
      </ul>
    </nav>
    <iframe src="chapter-1.html" name="chapter" title="Chapter text"></iframe>
  </body>
</html>
body {
  display: flex;
  height: 100vh;
  margin: 0;
}

nav {
  flex: 0 0 25%;
}

iframe {
  flex: 1;
  border: 0;
}

The iframe keeps the two-pane layout, but every chapter still shares one URL. Publishing each chapter as its own page, with the table of contents included on the server, gives every chapter an address people can bookmark and link to.

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?
🌍 Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
€5 / week

1K Weekly

1,000 monthly checks. Cancel anytime.

Get 1K Weekly →

Join teams across 40+ countries