HTML Iframes

Chapter 13 21 mins

Learning outcomes:

  1. What is <iframe>
  2. A simple <iframe> example
  3. Customizing the width and height
  4. Basic terminology related to <iframe>
  5. Session history of <iframe>s
  6. The name attribute
  7. The deprecated <frameset> and <frame>

What is <iframe>?

There are many many useful elements in HTML. Amongst that set we have the <iframe> element. Let's see what it actually is.

In its very basic sense:

The <iframe> element is used to load a webpage within another webpage.

The term iframe stands for inline frame. Let's dissect its meaning:

  • The word 'inline' means that the embedded webpage can appear anywhere between, i.e. inline with, a block of text.
  • The word 'frame' is generally used to refer to a container representing a separate webpage.

Iframes are frequently used to embed videos, maps, ads, and interactive utility apps (such as Codepen) into webpages.

While it's possible to put these features into a webpage without using <iframe>, it's usually much easier and more feasible in the <iframe>-way.

That's because the embedded webpage just thinks of itself as a 'normal' webpage being viewed by the user. The code inside an <iframe> sits inside a completely disparate environment, not affected by the CSS of the containing page.

The fact that certain things are easier with <iframe>s will become much clearer to you once you become a complete developer, knowing how to develop custom video player, ad libraries, and interactive utility apps, using JavaScript and other web technologies. It would be too early to explain all that technical jaron at this stage.

As a simple example of an <iframe>, one that you would've probably already witnessed before, suppose a blog has to embed a code snippet along with a program that can run that code (sometimes on another server) and show the response/output live, something like Codepen or JSFiddle.

In this case, the blog can simply embed a third-party's web application, meant to read code and produce its output in situ. And that's where the blog leverages the <iframe> element.

Anyways, moving on, <iframe> was introduced under the larger idea of 'frames', as a way to embed documents within documents, in HTML4, along with its friends <frame> and <frameset>.

<frame> and <frameset> were deprecated in HTML5 due to certain usability and accessbility issues, which we'll discuss later on in this chapter. <iframe>, however, still remains an integral component of many modern-day websites.

A simple example

At the very minimum, we just need to set the src of an <iframe> in order to get it into action.

The src attribute of an <iframe> element contains the URL of the webpage that ought to be displayed in the iframe.

We can embed both internal (also referred to as same-origin) and external (also referred to as cross-origin) URLs. (If we were only restricted to using internal URLs, <iframe>s wouldn't have been very useful.)

Let's create an iframe pointing to our very own landing page, www.codeguage.com:

<iframe src="/"></iframe>

Simple, right? Now, let's see the output this produces.

Live Example

Open up the link above and notice the small box representing the <iframe> containing our landing page. By default, browsers apply a border around it and set its width and height to 300px and 150px, respectively.

In this example, since we're already at www.codeguage.com, it's possible to set the src to just / in order for it to be taken as the root of the website.

However, if we wish to link to any external website, with a different origin, we'll have to use the complete URL (for e.g. just as happens with the href attribute of <a>).

This is shown below, for the demonstrative website example.com:

<iframe src="https://example.com/"></iframe>
Live Example

Customizing the width and height

By default, an <iframe> has its width set to 300 pixels and its height set to 150 pixels by browsers. This makes for a very small area to view the embedded webpage in the containing webpage.

Frankly speaking, if you want to use the <iframe> for non-demonstrative purposes, in a real application, you'd almost always want to change this default width and height.

And while you might just rely on CSS to do that, there are two standard <iframe> attributes that we can use to control its width and height: width and height, respectively.

The width attribute is used to specify the width of an <iframe>, in pixels. The same goes for height but obviously for the <iframe>'s height.

In the code below, we customize the width of the <iframe> that we had above, making it 400 pixels wide and 500 pixels tall:

<iframe src="/" width="400" height="500"></iframe>

Live Example

Feel free to play around with some width/height values as you like to.

Basic terminology

Now that we've seen a basic example of how to create an <iframe>, it's the high time to discuss about some common terminology used along with it, which will be used in this chapter as well.

First things first, an <iframe> creates a new browsing context.

Just as the name suggests:

A browsing context is a place where browsing could be done.

You are already aware of browsing contexts outside of <iframe>s. That is, browser windows/tabs are all instances of browsing contexts.

A window/tab can be used to browse the web and navigate across webpages, hence it's a browsing context.

A browsing context consists of a sequence of documents. Usually, this sequence of documents is referred to as the session history, or simply the history, of the context.

Moving on, every browsing context has a separate instance of its rendering engine, its JavaScript engine, and other suchlike resources. Just think of a browsing context as a browser tab except for that it might not have the interactive graphical elements that otherwise come with browser tabs, such as backward and forward buttons, etc.

Because a browsing context has a separate allocation of its resources, it's a good idea to keep <iframe>s (which create browsing contexts) to a minimum in order to conserve the memory of the underlying machine.

Browsing contexts can contain browsing contexts within them. We already saw this above, i.e. a tab/window can contain an <iframe>, which itself denotes a new browsing context.

A browsing context P that contains another browsing context C is called the parent browsing context of C. Similarly, C is called the child browsing context of P.

The top-level browsing context is one without any parent, hence the 'top-level', and it's almost always the main browser tab/window.

Sometimes these terms are also referred to with the word 'window'. So in that sense, we have parent windows, child windows, and top-level windows.

An <iframe> embeds a webpage into an existing webpage often called the embedded page. The containing webpage where the <iframe> element exists is called the embedding webpage.

And this is it for the basic terminology used while discussing about iframes.

Session history of <iframe>s

Iframes exhibit an interesting feature of navigation whereby there own browsing context's session history is shared with that of the top-level browsing context. In the following discussion, we get to learn what this means.

Reconsider the following HTML that we saw above:

<iframe src="/" width="400" height="500"></iframe>

It's just a simple <iframe> loading up our landing page.

Live Example

In the link above, try navigating our landing page inside the <iframe> (for e.g. go to the courses page, or maybe our blog page). As you do so, you'll notice all the navigations happening inside the <iframe>, not its parent window.

Now, once you make a couple of navigations, try going back by using the browser's back button.

At this point, you might expect the back button to take you to the previous page in the top-level window but that's NOT what will happen.

Give it a try. What do you witness?

The back button will instead take you to the previous page inside the <iframe>; the top-level window would remain as it is. Yes, that's right.

This is because <iframe>s share their session history with that of their top-level window.

So, for example, if you start off with the example page linked above, and then navigate to three pages in the embedded <iframe>, you would have to go back three times after that in order to get to the original entry of the example page.

By default, hyperlinks in HTML are opened up in the very browsing context that owns them. That is, hyperlinks inside a document embedded inside an <iframe> would open up inside that <iframe>.

But not all hyperlinks work this way...

Configuring a hyperlink's target

It's possible for some hyperlinks to be opened up right in the top-level browsing context even if they are part of an embedded document.

What's special about these links, i.e. <a> elements, is that they have a target attribute set on them with the value "_top".

The target attribute of an <a> element simply tells the browser about the place where the link should be loaded. _top is a special value that means that the link should be loaded in the top-level window.

By default, the target of <a> elements is set to _self, whereby a link opens up right in its very own browsing context; hence the name 'self'.

As we shall explore later on in this chapter, we can even use target to get a link to be opened up in a given <iframe>.

The name attribute

The name attribute of an <iframe> element is used to, well, name it.

But why would we want to do that?

<iframe>s are named so that they could be pointed to by hyperlinks (<a> elements) via their target attribute.

That is, we can set up the target attribute on an <a> element and assign it the name of an <iframe> (as assigned to its name attribute) so as to open the link in that <iframe>.

Sounds basic, right? Well it sure is.

Let's see an example.

In the code below, we have a hyperlink inside a paragraph, rendered along with an <iframe>:

<p>See our <a href="/courses/" target="frame1">courses page</a> in the following iframe.</p>

<iframe src="/" name="frame1" height="400" width="400"></iframe>

The hyperlink's target attribute is set to "frame1" which simply means that upon clicking it, the corresponding URL would be loaded not in the top-level window but rather in an <iframe> named frame1, which is the following <iframe>.

Live Example

The deprecated <frameset> and <frame>

Back in time when <iframe> was introduced with HTML4, we also got two other frame-related elements alongside it, namely <frameset> and <frame>.

With HTML5, however, both these elements got deprecated from the language. Modern-day code, as per the standard's recommendation, should NOT use <frameset> and <frame>.

In this section, we shall understand what exactly was <frameset> and <frame>; why were they popular at a time: and why they lost that position, eventually finding themselves in the class of obsolete HTML elements.

This section is optional, purely for informative purposes, so if you want to, you can skip it.

We already know by this stage that the <html> element could only contain two elements, <head> and <body>. Well, with <frameset>, the case was slightly different — <html> could also have a <frameset> element as its child and in that case, it would be considered as the 'body' element.

As per its name, <frameset> is used to denote a set of frames, each denoted via the <frame> element. The <frame> element works similar to <iframe>, just that it could only be a part of <frameset> (unlike <iframe>).

Going back in time again, using <frameset>, it was possible to have multiple documents within a main HTML document, all displayed in a nice visual layout. So what developers started to do was to separately develop pages representing headers, footers and side menus for websites and then embed those pages along with pages containing actual content in the main pages of their websites.

This had the consequence that the header and footer all remained fixed in the browser's view while navigations took place in the frame containing the actual content.

The modern-day analogue of this old approach is called a SPA (Single-Page Application), and it's quite famous — Spotify, for example, is a SPA.

SPAs don't use the deprecated and inefficient <frameset> approach; instead, they rely on sophisticated JavaScript APIs to power a web application.

<frameset> was surely handy during its era when server-side scripting wasn't as easy and intuitive as it's today and when JavaScript wasn't that mature to be able to heavy-lift such responsibilities all by itself.

But as one can probably guess, <frameset> wasn't without its issues — serious issues.

Search engines had trouble ranking pages featuring <frameset> due to there being no actual content in the pages themselves (the pages just had multiple <frame>s).

Even if somehow they did index those pages, they stored the actual content pages that were themselves linked in those <frameset>-based pages. The result: opening a link from search engines ended up on those content pages, that didn't have any header, any footer, any side menu — just about nothing.

Moreover, it was particularly still somewhat tedious and error-prone to code suchlike websites using <frameset>. Whole webpages had to be devoted to making things such as headers and footers which was a little bit taxing.

Last but not the least, <frameset> led to accessibility issues, in particular for assistive screen-reading technologies.

All in all, it became clear at one point in the early days of the web, when this <frameset> approach was somewhat popular, that there was a need of a much more sophisticated, formal and programmatic way of getting these features on the web.

A way where we didn't have to use HTML documents for purposes they weren't actually meant for (i.e. creating just headers and footers).

And so came in a plethora of APIs in JavaScript to allow for creating webpages similar in functionality to <frameset>-based webpages, with fixed headers and footers, and only changing content.

Likewise, in favor of these simpler, better, and more efficient APIs, <frameset> and <frame> were both officially deprecated in HTML5.

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage