acerca de HTML

Referencia de etiquetas

Etiqueta frame en HTML: obsoleta y migración de marcos

La etiqueta <frame> está obsoleta y no debe usarse en páginas nuevas. Cargaba un documento en una región de un <frameset>, por ejemplo un menú junto a otra página con el contenido. Hoy se rediseña esa estructura con HTML y CSS; se reserva <iframe> para un documento que realmente necesite incrustarse. El HTML Living Standard prohíbe la autoría de frame, frameset y noframes.

Ejemplo histórico y contexto de frame

Este bloque sirve para reconocer código antiguo; no es HTML vigente ni una demostración ejecutable:

<frameset cols="220,*">
  <frame src="menu.html" name="menu" title="Navegación">
  <frame src="contenido.html" name="contenido" title="Contenido">
</frameset>

El diseño pretendía mostrar dos documentos: menu.html en una columna de 220 píxeles y contenido.html en el espacio restante. Los archivos se cargaban por separado; no eran hijos escritos dentro de <frame>. No se exige que un navegador actual reproduzca este diseño.

En HTML 4.01 Frameset, <frame> era un elemento vacío: no contenía texto ni llevaba </frame>. Su padre era <frameset>, que podía anidarse y ocupaba el lugar de <body> en el documento contenedor. No se colocaba dentro del cuerpo de una página moderna. La referencia histórica de W3C documenta esta sintaxis.

Cambiar src cambiaba el documento inicial del marco; cambiar cols afectaba a la distribución, porque era un atributo de <frameset>. Retirar un <frame> no integra automáticamente el contenido de su archivo en la página.

Frame, frameset e iframe

<frameset> repartía la ventana en marcos y cada <frame> seleccionaba un documento. <iframe> es un elemento vigente que incrusta otro documento dentro del contenido de una página con <body>. Tiene apertura y cierre: <iframe …></iframe>.

Por tanto, frame e iframe no son la misma etiqueta. Sustituir todos los marcos por iframes conservaría documentos separados y sus problemas de navegación; no crea por sí solo una página adaptable o accesible. Para un menú y contenido propios, reúne la estructura en una página con <nav> y <main>. Si el sitio tiene varias páginas, comparte la navegación mediante una plantilla durante su generación o en el servidor.

Migración a navegación y contenido principal

Guarda este documento como biblioteca.html en UTF-8 y ábrelo en el navegador. Incluye todo el CSS y no necesita servidor, otros archivos ni JavaScript.

<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Biblioteca del barrio</title>
    <style>
      body {
        margin: 0;
        padding: 1rem;
        font-family: sans-serif;
        line-height: 1.6;
        color: #222;
        background: #fff;
      }
      a { color: #0645ad; }
      a:focus-visible { outline: 3px solid #0645ad; outline-offset: 3px; }
      .pagina { max-width: 64rem; margin-inline: auto; }
      nav ul { padding-inline-start: 1.5rem; }
      main { min-width: 0; }
      @media (min-width: 48rem) {
        .pagina {
          display: grid;
          grid-template-columns: 14rem minmax(0, 1fr);
          gap: 2rem;
        }
      }
    </style>
  </head>
  <body>
    <a href="#contenido">Saltar al contenido</a>
    <div class="pagina">
      <nav aria-label="Biblioteca">
        <ul>
          <li><a href="#talleres">Talleres</a></li>
          <li><a href="#horarios">Horarios</a></li>
        </ul>
      </nav>
      <main id="contenido" tabindex="-1">
        <h1>Biblioteca del barrio</h1>
        <h2 id="talleres" tabindex="-1">Talleres</h2>
        <p>El club de lectura se reúne los miércoles a las 17:00.</p>
        <h2 id="horarios" tabindex="-1">Horarios</h2>
        <p>Abrimos de lunes a viernes, de 9:00 a 18:00.</p>
      </main>
    </div>
  </body>
</html>

<nav> identifica la navegación principal y <main> el contenido dominante. Hay un solo main. Los destinos admiten foco mediante tabindex="-1" sin añadir paradas a la secuencia de Tab.

En móvil verás navegación y contenido uno debajo del otro. Desde 48rem, la consulta de ancho activa dos columnas con CSS Grid. La lectura del HTML conserva el mismo orden.

Los enlaces cambian la URL a biblioteca.html#talleres o #horarios; Atrás y Adelante recorren esos destinos. Para documentos distintos, utiliza sus URL reales: se cargará la página completa. Desaparece la dependencia de target="contenido", que antes dirigía enlaces al marco nombrado. Revisa también un posible <base target="contenido"> heredado. Conserva o redirige las URL antiguas cuando publiques la migración.

Prueba Tab y Enter para saltar al contenido y abrir ambos destinos. Comprueba foco, URL e historial a 375 y 1280 píxeles, con JavaScript deshabilitado. Retira el CSS: permanece todo el contenido en el orden de lectura, sin columnas.

Iframe solo para un documento independiente

Si los horarios deben mantenerse como documento separado, guarda este archivo como horarios.html junto a biblioteca.html:

<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Horarios de la biblioteca</title>
  </head>
  <body>
    <h1>Horarios de la biblioteca</h1>
    <p>De lunes a viernes, de 9:00 a 18:00.</p>
  </body>
</html>

Añade este fragmento dentro del main del primer ejemplo, sustituyendo su sección de horarios. Conserva un destino horarios para el enlace del menú:

<h2 id="horarios" tabindex="-1">Horarios</h2>
<iframe
  src="horarios.html"
  title="Horarios de la biblioteca"
  style="width: 100%; height: 12rem; box-sizing: border-box; border: 1px solid #555;"
></iframe>
<p><a href="horarios.html">Abrir los horarios como página completa</a>.</p>

Verás el segundo documento dentro de una región con borde y un enlace para abrirlo directamente. El atributo title describe el iframe para sus usuarios; no sustituye al <title> del documento ni a su contenido accesible. Comprueba que puedes entrar y salir con el teclado.

Los estilos externos no se aplican al documento incrustado. Su altura tampoco se ajusta automáticamente al contenido. Un servidor externo puede impedir la incrustación mediante sus políticas; añadir un iframe no concede permiso. El enlace exterior debe seguir disponible si se bloquea la carga: no se trata de contenido alternativo dentro de <iframe>.

Atributos antiguos y reemplazos

Los siguientes valores corresponden a HTML 4.01, no a recomendaciones actuales:

Atributo de frameEfecto históricoDecisión al migrar
srcURL del documento inicialIntegrar su contenido o usar src de iframe si procede
nameNombre para destinos de enlacesQuitar los target antiguos y usar URL o fragmentos
scrollingauto por defecto; yes forzaba desplazamiento, no lo impedíaPermitir leer el contenido completo; revisar el desbordamiento
frameborder1 por defecto; 0 pedía ocultar separadoresControlar los bordes mediante CSS
noresizeBooleano: presente impedía redimensionar; ausente no lo impedíaDiseñar un tamaño adaptable
marginwidth, marginheightMárgenes internos en píxeles positivos; valor predeterminado del navegadorDefinir espacio con CSS en el documento correspondiente

title, id y class eran atributos comunes, no exclusivos de los marcos. name no era el título legible del marco. No traslades automáticamente los atributos antiguos a iframe: scrolling, frameborder y los márgenes también son obsoletos allí; noresize no es un atributo vigente de iframe.

border, padding y grid-template-columns son propiedades CSS. element.style.border es acceso al estilo mediante JavaScript; no convierte un atributo histórico en válido.

Errores frecuentes y preguntas

¿Qué reemplaza los marcos de una página? Normalmente un documento con navegación, contenido y CSS. Usa iframe únicamente para una incrustación necesaria, con un título descriptivo y una salida mediante enlace.

¿Por qué no aparece frame dentro de body? Revisa primero el contexto: pertenecía a <frameset>. En una página actual, reconstruye la estructura; añadir un cierre o cambiar atributos no corrige su obsolescencia.

Evita dejar enlaces dirigidos a marcos inexistentes, ocultar contenido con scrolling="no" o asumir que eliminar un marco conserva sus datos. <noframes> era una alternativa para la arquitectura antigua, no un mecanismo moderno de fallback. Para escribir los enlaces de la migración, consulta la guía de <a>.

Compatibilidad y fuentes

Estado revisado el 3 de octubre de 2026. MDN marca <frame> como obsoleto. El estándar mantiene reglas de procesamiento para documentos heredados, lo cual no permite usarlo en autoría nueva ni garantiza un resultado idéntico entre navegadores. La sintaxis histórica se contrasta con HTML 4.01; la migración utiliza las fuentes actuales de HTML, CSS y accesibilidad enlazadas en la guía.