To embed, or not to embed - that is the question.
Introduction
This article warns about the disadvantages of embedding certain types of content on web pages. Note: The phrase "embed" or "embedding" as used in this document refers to the process of loading external content with a web page as if it was part of the page itself. In other places the phrase "embedding" is occasionally used to refer to converting binary data into so-called BASE64 data. BASE64 data can be placed directly in an HTML document. This is a fundamentally different process.
Examples of external content that can be embedded into a web page:
- Images (JPEG, GIF, PNG)
- Other HTML documents
- Audio and/or Video
- Scalable Vector Graphics (SVG)
- Adobe Acrobat and other (possibly proprietary) document formats
- Macromedia Flash and other (possibly proprietary) multimedia formats
- Java applets
Several HTML elements perform this function, for example: <img>, <object>, <applet> and <iframe>.
Static images are widely accepted as web content, graphic browsers usually handle image formats such as JPEG, GIF or PNG natively. To embed other types of external content browsers usually need another application and a plugin (Mozilla, Opera), or in the case of Internet Explorer the proprietary MS technology ActiveX. External content like Audio and/or Video may once have been used as optional fluff, they are increasingly being used as essential content. This means that we should take accessibility issues regarding external content seriously.
The correct way to embed: using the <object> element
The <object> element is the standard compliant way to embed external content. The <embed> element was never incorporated into the standards, although relatively widely implemented, it's use should be avoided. Note that if you use <object>, the external content will also be available to old UAs like Netscape 4 that do not support using the <object> method provided that a link is used as the inner most element of an object cascade.
W3C uses the phrase "generic inclusion" to describe the function of the <object> element, this can lead to confusion with techniques like Server Side Inclusion (SSI) which is a fundamentally different process, so I've avoided using that phrase here.
Content types
Audio & Video: don't embed it
Modern media player software like MS MediaPlayer 9 and Realplayer 9 take up a lot of system resources and can take a long time to start up. Embedding usually causes the user's mediaplayer to be hoisted into memory just to display a User Interface widget on the page. Users should first be allowed to decide wether or not to play the Audio/Video.
Media Players that can be embedded into a web page commonly do not allow a user to prevent content from starting automatically. Unfortunately many web authors attempt to do just that, this is a common cause of user irritation that has resulted in a resentment against embedding not unlike the way unrequested popups are currently despised by most users.
So how do we offer audio and/or video on a web page?
Plain old links to the rescue. Get creative with graphics if you don't like the look of a text link: (I'm no designer, you can probably do better)
Click the Play button to stream the video clip (Windows Media format), or download the video clip (WM or XviD/Vorbis format).
But having to download the media takes too long?
This can be solved by linking to redirector files to initiate streaming.
Offering both an option to stream and download will be appreciated by many users.
HTML: don't embed it
Two techniques are often confused: (server side) inclusion and embedding.
Server side inclusion
This requires a server side technology like Apache's SSI, or a server side scripting language (PHP for example). This is most commonly used to merge chunks of code into documents (repetitive content like navbars for example). The result of this process does not cause more viewports to be presented to the user.
Embedding (client side)
This cannot be used to merge chunks of code into a document, instead the UA opens a new viewport inside an existing viewport. The UA displays another (complete) web page in this new viewport.
Embedded HTML demo:
First you have to ask yourself why you would want to do this, remember: you cannot use embedding to include code fragments. Note that embedded HTML has no intrinsic width and/or height, so you need to specify a width and height for the new viewport (in the HTML, not with CSS), using CSS to set the width and/or height to auto will not work.
Problems caused by embedding HTML:
Users will typically have to use a mouse to drag the scrollbar on the new viewport window to get the content to scroll, IE does not support mouse-over mouse-wheel scrolling. UA support for keyboard operation is poor and it's not intuitive to most users. Ergo: don't embed HTML, it causes serious problems for users.
Embedding GIF, PNG or JPEG images
Theoretically we should use the <object> element to embed all forms of external content, including images. Unfortunately MS Internet Explorer's support for embedding images with the <object> element is too buggy, so in practice we are stuck with the <img> element for the near future.
Embedded PNG image demo using the <object> element:
When viewed with IE it appears to take the image and insert it on a self generated temporary document (hence the margins), to display it, it then incorrectly opens a new viewport.
Code used:
<object data="img/butterfly.png" type="image/png" width="172" height="122">
<a href="img/butterfly.png">Image of a butterfly</a>
</object>
Embedding Scalable Vector Graphics (SVG)
A seperate SVG viewer may take up considerable system resources and take some time to start up (the Adobe SVG plugin for example). This may be less of an issue when SVG is supported natively on the client such as Opera 8 (SVG Tiny), Opera 9 (SVG Basic) or recent Firefox's. This should be taken into account before deciding to embed SVG content, the conservative choice is to link.
Embedded SVG image demo:
Code used:
<object data="img/butterfly_vector.svg" type="image/svg+xml" width="170" height="120" class="img">
<a href="img/butterfly_vector.svg">[<acronym>SVG</acronym> Image of a butterfly</a>] (Using the link to view the image requires a stand alone <acronym>SVG</acronym> viewer and your browser needs to be configured to use this player)
</object>
IE, the Adobe plugin and scripted SVG content
Note that the Adobe plugin when used in IE disables scripting when <object> is used. Adobe recommends using the non valid <embed> element instead. By using an MS "uplevel revealed" conditional comment IE can be fed an embed element, other browsers can then be fed an object element which is switched off for IE using CSS and/or JavaScript.
Code example:
CSS
.svg{display:none}
*>.svg{display:inline}
HTML
<!--[if IE]><embed src="img/butterfly_vector.svg" width="170" height="120"><![endif]--><object data="img/butterfly_vector.svg" type="image/svg+xml" width="170" height="120" class="svg">
<a href="img/butterfly_vector.svg">[<acronym>SVG</acronym> Image of a butterfly</a>] (Using the link to view the image requires a stand alone <acronym>SVG</acronym> viewer and your browser needs to be configured to use this player)
</object>
The above code allows scripting of SVG content in IE without invalidating the HTML code. The drawback is that if CSS is disabled in IE the SVG content is rendered twice. It's unlikely that IE users have CSS disabled, but if they do the content should remain fully usable, so this can be considered as a negligible issue. For optimal reliability another conditional comment could be used instead of the child selector hack to switch the object off for IE.
Adobe Acrobat PDF documents: don't embed it
Users should first be allowed to choose whether or not they want to view the document, embedding takes that choice away from them. Having the Acrobat application and plugin loading automatically can be a strain on a user's computer resources, the later versions of Acrobat reader are notoriously bloated applications. Note that document formats such as PDF are rarely a suitable format to use on the world wide web. If you cannot avoid using the format (very few good reasons exist) then link to the document instead of trying to embed it.
Flash
Personally I dispise Flash content, it's creator Macromedia and their policies (they famously used to adverstise Flash as a replacement of HTML). That said, there can be a need for the type of functionality offered by Flash. The Macromedia Flash V6 & V7 player/plugin is a relatively lightweight application in comparison to for example modern Media Players. Unlike Media Players it is uncommon for people to have a stand alone Flash player application available and configured on their system. Embedding is therefore probably the best way to offer Flash content provided that it's coded in a accessible way. Given that Flash rendering is available on a lot of user systems, the format may be considered as the best of a bad lot with regard to accessibility. (Note: Macromedia claims that Flash V8 has features to make the content more accessible)
Flash checklist:
- Make sure that it's only used for things that cannot be done properly.
- Create an version in a format like SVG if possible. Nest both together to create a solution that adapts automatically to the capabilties of the user's system, and code fallback links for those rare situations that people have standalone viewers for these file formats available and configured. (See below for an Embedded SVG image with a Flash fallback demo)
Embedded Flash image demo:
Note: See the Flash Satay article on "A List Apart" for an optional hack to get IE to stream Flash content (vital for larger Flash files).
Code used:
<object data="img/butterfly.swf" type="application/x-shockwave-flash" width="172" height="122">
<a href="img/butterfly.swf">[Flash image of a butterfly</a>] (Using the link to view the image requires a stand alone Macromedia Flash viewer and your browser needs to be configured to use this player.)
</object>
Embedded SVG image with a Flash fallback demo:
Note: this example demonstrates the theory, various browsers do not render this correctly.
Code used:
<object data="img/butterfly_vector.svg" type="image/svg+xml" width="170" height="120" class="img">
<object data="img/butterfly.swf" type="application/x-shockwave-flash" width="172" height="122">
<param name="movie" value="img/butterfly.swf">
<p><a href="img/butterfly_vector.svg">[SVG</a> or <a href="img/butterfly.swf">Flash</a> image of a butterfly] (Using the links to view the image requires a stand alone SVG or Flash viewer and your browser needs to be configured to use this player.)</p>
</object>
</object>
Footnotes
- The code examples use a 2 or 3 stage nested cascade, a browser first attempts to render the outer generic code, if it is unable to render the code (or configured not to), the inner code is evaluated until it finds a method it can use. In the code examples if a browser cannot present the embedded object then it should present a regular text link.
- Note that the content "type" value as used in the code examples is used by UAs only to determine if there's a point in accessing the external resource, once a UA has accessed it the content's mime type as transmitted via the http "Content" header is used, so make sure that your web server's mime types are configured correctly.