Skip to main content
HTML Validation

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

About This HTML Issue

The <frame> element is obsolete, so the content each frame loads has to move into the page itself or into an <iframe> inside a normal <body>.

A <frame> only works inside a <frameset>, where it loads a separate HTML file into one pane of the browser window. The validator reports this message once for every <frame> on the page, and the <frameset> around them gets a message of its own. Moving the frames into a <body> doesn't help: the parser drops a <frame> there and reports it as a stray start tag. The frames and the frameset have to be replaced together, and when the frameset only wraps another site in a single frame, an HTTP redirect to that site replaces both.

What replaces each frame depends on what it holds. A header or menu that every page shares belongs in the page itself, written directly or pulled in with a server-side include or a template, so it lives at the same URL as the content around it. A document that has to stay separate can load in an <iframe>. Iframes take src and name just as frames did, so links with a matching target keep loading into them, and the validator stops warning that name is never allowed on <frame>. Give each iframe a title describing what it shows, since screen readers announce it.

The presentation attributes of a frame don't carry over. On an <iframe>, frameborder, scrolling, marginwidth and marginheight are obsolete too, and the validator warns about each one. Remove the border with border: 0 in CSS. Scrollbars and margins belong to the document loaded inside, so set overflow and margin in that document's own stylesheet. noresize needs no replacement, since an iframe has no draggable border between panes.

Invalid example

A header frame above a catalog frame:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Garden supplies</title>
  </head>
  <frameset rows="80,*">
    <frame src="header.html" scrolling="no" noresize frameborder="0">
    <frame src="catalog.html" frameborder="0">
  </frameset>
</html>

Valid example

The header is part of the page (on a real site it would come from an include), and the catalog keeps loading from its own file in an iframe:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Garden supplies</title>
    <style>
      iframe {
        width: 100%;
        height: 80vh;
        border: 0;
      }
    </style>
  </head>
  <body>
    <header>
      <a href="/">Garden supplies</a>
    </header>
    <iframe src="catalog.html" name="catalog" title="Product catalog"></iframe>
  </body>
</html>

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