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,
<frameset> were all the rage in the late 90s and early 00s. At a time where CSS wasn't really a thing 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 1990's solution to problems the web development community still faces today, such as code modularity and bandwidth usage reduction, with a lot of 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 limitation, and what its legacy to the modern web is.
<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
<!-- 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
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
<!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 to decide 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
target allowed click on
<a> to open in a cell of the
<frameset>. A few special target keywords 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>
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
This very feature could also help, in a way, with performance: by only reloading parts of the page when navigating, it made for smaller payloads.
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.
Search engine optimization was really hard to achieve using
target on a link to open a page on a given
<frame> meant that the window's main url was not changing: single pages did not have a publically accessible url.
As a result, search engines were often indexing single frames separately, which led users to land on a "broken" website, and an information without context.
As they were multiple screens in one,
<frameset> were also poorly supported by screen readers, making it challenging to build accessible websites.
On the performance side of things, while they offered some advantages after the initial load, these websites meant that many more HTTP requests had to be done when being accessed for the first time.
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 and performance challenges it poses.
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 (for the most part) from the
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 accross 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.