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, <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 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
.
<!-- 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>
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:
<!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 were defined, such as the still overused _blank
, allowing to open the link in a new window.
<A href="contact.html" target="main" title="[...]">Contact</A>
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"
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 wrote a terrific blog post about "The 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.
Top comments (0)