acerca de HTML

Referencia de etiquetas

Etiqueta frameset en HTML: obsoleta y diseños actuales

La etiqueta <frameset> está obsoleta y no debe usarse en páginas nuevas. Dividía la ventana en marcos que mostraban documentos distintos, por ejemplo un menú junto a una lección. Hoy ese diseño suele resolverse con un documento estructurado y CSS Grid o Flexbox. El estándar vigente exige abandonar los marcos antiguos; esta guía explica cómo reconocerlos y migrarlos.

Ejemplo histórico: menú y lección separados

Este fragmento documenta código antiguo; no es una demostración para ejecutar ni una recomendación actual:

<frameset cols="25%,75%">
  <frame src="menu.html" title="Menú">
  <frame src="leccion.html" name="contenido" title="Lección">
</frameset>

Pretendía reservar un cuarto de la ventana al menú y tres cuartos a la lección. menu.html y leccion.html eran documentos independientes, con carga y desplazamiento propios; sus nombres describen archivos antiguos, no recursos que debas descargar para esta guía.

En HTML 4.01 Frameset, <frameset> aparecía después de <head> y sustituía a <body>. Contenía uno o más <frame> o conjuntos <frameset> anidados y, opcionalmente, un <noframes> con contenido alternativo. Tenía apertura y cierre; <frame> era vacío. Esa estructura no es válida para autoría actual bajo <!DOCTYPE html>.

Cómo funcionaban rows, cols y los destinos

Los dos atributos específicos de distribución recibían listas separadas por comas:

Atributo históricoQué repartíaEjemplo
colsAnchura entre columnascols="240,*": una columna de 240 píxeles y otra con el espacio restante
rowsAltura entre filasrows="20%,80%": dos filas con esas proporciones

Aceptaban números en píxeles, porcentajes y proporciones como * o 2*. cols="*,2*" repartía el espacio relativo en proporción 1:2. Si faltaba un atributo, su valor histórico era 100%: una sola fila o columna. Podían combinarse para formar una cuadrícula. Son reglas de distribución histórica, no sintaxis de CSS.

src y name pertenecían a <frame>, no a <frameset>. Un enlace con target="contenido" cargaba su destino en el marco llamado contenido. El nombre identificaba el destino; title lo describía. La navegación entre marcos podía cambiar la lección sin cambiar el menú. Compartir la URL exterior no siempre reproducía esa combinación, y varias zonas con desplazamiento complicaban la lectura en pantallas pequeñas.

Los atributos globales id, class y title no eran atributos de distribución. En la solución actual, grid-template-columns y gap son propiedades CSS; no atributos HTML ni instrucciones JavaScript. Tampoco 1fr equivale automáticamente al antiguo *: Grid reparte espacio dentro de un diseño con sus propias reglas de tamaño.

Migración actual con CSS Grid

Guarda este documento completo como leccion.html, con codificación UTF-8, y ábrelo en un navegador. Incluye todo el contenido y CSS; no necesita otros archivos, un servidor ni JavaScript.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Cultivar albahaca</title>
  <style>
    * { box-sizing: border-box; }
    body {
      max-width: 70rem;
      margin: auto;
      padding: 1rem;
      font-family: system-ui, sans-serif;
      line-height: 1.6;
      color: #172b3a;
      background: #fff;
    }
    a { color: #074f85; }
    :focus-visible { outline: 3px solid #074f85; outline-offset: 3px; }
    .pagina { display: grid; gap: 1.5rem; margin-top: 1rem; }
    nav, main { min-width: 0; }
    nav { padding: 1rem; background: #edf4f8; }
    footer { grid-column: 1 / -1; border-top: 1px solid #8798a4; }
    @media (min-width: 48rem) {
      .pagina { grid-template-columns: minmax(12rem, 1fr) minmax(0, 3fr); }
    }
  </style>
</head>
<body>
  <a href="#contenido">Saltar al contenido</a>
  <div class="pagina">
    <nav aria-label="Temas de la lección">
      <h2>Temas</h2>
      <ul>
        <li><a href="#siembra">Siembra</a></li>
        <li><a href="#cuidados">Cuidados</a></li>
      </ul>
    </nav>
    <main id="contenido" tabindex="-1">
      <h1>Cultivar albahaca</h1>
      <section id="siembra">
        <h2>Siembra</h2>
        <p>Prepara una maceta con drenaje y coloca las semillas en el sustrato.</p>
      </section>
      <section id="cuidados">
        <h2>Cuidados</h2>
        <p>Comprueba la humedad de la tierra antes de regar.</p>
      </section>
    </main>
    <footer>
      <p>Cuaderno de cultivo: lección de albahaca.</p>
    </footer>
  </div>
</body>
</html>

En una ventana de al menos 48rem aparecen menú y contenido en dos columnas, con el pie <footer> debajo de ambos. En móvil se apilan: navegación, contenido y pie. Ese mismo orden está en el HTML; no depende de una reordenación visual. El enlace inicial lleva al contenido, cuyo tabindex="-1" permite recibir el foco sin añadirlo al recorrido habitual de Tab.

Prueba los enlaces con Tab y Enter, estrecha la ventana y desactiva JavaScript: la lectura y la navegación deben seguir disponibles. Desactivar el bloque <style> deja un documento comprensible en una columna. Retirar solo grid-template-columns también apila el contenido; no elimina ninguna lección. En el código antiguo, retirar <frameset> no fusionaba los archivos: había que migrar su contenido.

Qué debe cambiar además del diseño

Traslada los enlaces de menu.html a <nav> y el contenido útil de leccion.html a <main>. Los encabezados, imágenes y textos alternativos siguen siendo necesarios. Revisa rutas relativas, identificadores repetidos y scripts que dependían de parent, top o de nombres de marcos.

Aquí se carga un único documento. Los enlaces #siembra y #cuidados cambian el fragmento de la URL y permiten volver con el historial; no solicitan otro archivo. Puedes copiar leccion.html#cuidados para abrir directamente ese tema. Si el sitio tiene muchas lecciones, conserva páginas completas con URLs propias y genera la navegación compartida mediante plantillas. Mantén las URLs antiguas importantes o configura redirecciones en el alojamiento: cambiar el layout no las conserva por sí solo.

Errores frecuentes y preguntas

¿Frameset va dentro de body? No en su modelo histórico: sustituía al cuerpo del documento. Ponerlo dentro de <body> o copiar un doctype antiguo no lo convierte en una técnica vigente.

¿Cómo hago columnas sin frameset? Usa estructura HTML apropiada y CSS Grid, como arriba, o Flexbox. Elige tamaños según el contenido y el ancho disponible; cambiar cols por una propiedad CSS exige diseñar la adaptación.

¿Conviene sustituir cada marco por un iframe? Usa <iframe> solo si necesitas incrustar un documento independiente. No lo uses como sustitución automática para el menú y las lecciones: conservarías documentos separados y tendrías que resolver sus límites de navegación y acceso.

<frame> representaba cada marco; <noframes> ofrecía su alternativa histórica. Hoy <nav> identifica la navegación y <main> el contenido principal. Un <div> puede agruparlos para aplicar el layout, pero no sustituye su significado.

Compatibilidad y fuentes

Fuentes revisadas el 4 de octubre de 2026. El Living Standard: funciones obsoletas prohíbe usar <frameset> en contenido nuevo. MDN: <frameset> también lo marca como obsoleto y advierte sobre una posible retirada. Que un navegador todavía interprete marcos no hace válido ese código.

La sintaxis antigua se contrasta con W3C: marcos en HTML 4.01. La migración utiliza CSS Grid: cuadrícula explícita, con contenido que permanece disponible si no se aplica CSS.