HTML postmortem: frameset and its legacy
Tags: webdev, html
Published: 2020-01-13 03:35:36

---
title: HTML postmortem: frameset and its legacy
published: true
description: Ever wondered where the target=_blank attribute came from, what it means and why it behaves the way it does? A little bit of HTML history might help with that 🤓📖.
tags: webdev, html
cover_image: https://thepracticaldev.s3.amazonaws.com/i/726wkkumk0jod4whj5ke.png
---
Ever wondered where the `target="_blank"` attribute came from, what it means and why it behaves the way it does? A little bit of HTML history might help with that 🤓📖.

Part of the [HTML 4 standard](https://www.w3.org/TR/html4/present/frames.html), `<frame>` and `<frameset>` were all the rage in the late 90s and early 00s. At a time where **CSS** wasn't commonly used for layout and [WYSIWYG Web editors](https://en.wikipedia.org/wiki/HTML_editor#WYSIWYG_HTML_editors) were very popular, `<frameset>` offered a simple way of building somewhat complex layouts by allowing to split the browser's window into **a grid of separate HTML documents**. In a way, they were the old web's solution to challenges the web development community still faces today, such as code modularity and bandwidth usage reduction, and came with many important limitations and side effects we'll go over in this article.

Let's explore together how this now-deprecated web dinosaur that is `<frameset>` worked, what were some of its limitations, and what its legacy to the modern web is.

---

## How did it work?
The `<frameset>` tag took the place of the `<body>` tag: it was used to indicate to the browser that it was meant to load multiple HTML documents, represented as `<frame>` elements, and how they were supposed to be displayed on the screen, using `cols` and / or `rows`.

```html
<!-- This is late 90s HTML, tags were SCREAMED! -->
<FRAMESET cols="25%, 75%">
    <FRAME name="sidebar" src="menu.html">
    <FRAME name="main" src="home.html">
</FRAMESET>
```

![Simple frameset demo with two columns](https://thepracticaldev.s3.amazonaws.com/i/55yyae0b3e951rffqa97.png)

It was even possible to nest `<frameset>` tags to use the `cols` and `rows` attributes in combination, allowing to build more complex grids.

A special **HTML Doctype** was available and was _"sometimes"_ needed to allow for the rendering of `<frameset>`-related tags:
```html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd">
 ```

Having multiple separate documents in a single browser window led to some complications, the first of them being **deciding where a given link should open**. Hence was created the `target` attribute for the `<a>` tag, which stands for _"frame target"_: If provided the name of a given `<frame>`, `target` allowed click on `<a>` to open in a cell of the `<frameset>`. A [few special targets](https://www.w3.org/TR/html4/types.html#type-frame-target) were defined, such as the still overused `_blank`, allowing to open the link in a new window.

```html
<A href="contact.html" target="main" title="[...]">Contact</A>
```

![Screenshot showing that opening another page in a frameset does not change the url](https://thepracticaldev.s3.amazonaws.com/i/89t7w457hg0h5swzsg57.png)


Finally, since this patchwork of HTML documents was meant to be a single page, **JavaScript had to be able to talk and share information between frames, and even sometimes across domains** ... which we'll talk about a bit more when discussing the **security issues of framesets**.

---

## What was it "good" for?
The main advantage of `<frameset>`-based websites was that they allowed for **code reuse and modularity**: splitting a webpage in separate documents, organized by role, made possible to focus on the development of a part without affecting the other, of containing code and its effects in a `<frame>`.

This very feature could also help, in a way, with **performance**: only reloading parts of a page when navigating made for smaller payloads, which is still relevant today but was critically important in the before-broadband-internet times.

But more importantly, **they were an easy-to-use layout tool**, that styling alone could not help achieve at the time: there was no _"more semantically"_ correct way of doing things available at the time.

---

## Risks and limitations
**Proper search engine indexation** was really hard to achieve using `<frameset>`. Using `target` on a link to open a page on a given `<frame>` meant that the window's main url was not changing: **`<frameset>` pages did not have a publicly accessible url**, while individual frames where still crawlable.
As a result, search engines were often indexing single frames separately, which led users to land on _"broken"_ websites, and on an information deprived of its intended context.

As they were multiple in effect _"screens"_ in one, `<frameset>` were also poorly supported by **screen readers**, making it challenging to build **accessible websites**.

On the **performance side of things**, `<framset>`-based websites had a significant advantage once the first load was done: as navigation was happening on generally one or two of the frames, most of the frames didn't need to be reloaded. But this also meant that, on first load, the browser had to download and parse more HTML documents.

Finally, **they were and still are a security headache**: the ability for frames to interact with their parents and siblings via JavaScript - even across domains - gave birth to many attacks pattern we are still reckoning with today.

---

## What remains of it today?
Besides everything that it taught us, and the millions of older websites out there that are still using `<frame>` and that would have been much different otherwise, I feel like one of `<frameset>`'s main legacy to modern web development is the `target` attribute for the `<a>` tag, and the security, accessibility and performance challenges it poses.

When using `target="_blank"`, [we must add `rel="noopener noreferrer"`](https://developers.google.com/web/tools/lighthouse/audits/noopener) to let the browser know that **it should not allow the new window to access the window that called it**. While modern browsers implement some default protections to prevent leaks, without `rel="noopener noreferrer"`, it is still possible to access **some** of the caller's information via `window.opener`, a behavior inherited _(to a certain extent)_ from the `<frameset>` era.

But access to `window.opener` _(the caller's window object)_ is also the main reason why `target="_blank"` can be a threat to performance: sharing objects across pages means sharing memory, which gives the browser less opportunities to separate processes and threads. [Jake Archibald](https://twitter.com/jaffathecake) wrote a terrific blog post about ["The performance benefits of rel=noopener"](https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/) back in 2016.

Its dizzying, sometimes, to look back at the origin of all things web and see how ideas from the past _- that we sometimes completely forgot about -_ still have an important impact on our everyday lives, and how things evolved for the better.