Flash Player guidance for Internet Explorer 11 and Microsoft Edge

A great deal of flash content, which works in Internet Explorer 10 or earlier, may behave incorrectly with Microsoft’s latest browsers. This blog post will list technical differences to help developers debug why their site might be broken in Internet Explorer 11 or Microsoft Edge.  This is truly a deep dive into the workings of Flash Player and browser detection.

For those that merely want our recommended best practice to embed Flash Player in your HTML code, the answer is simply use SwfObject 2.3.  Documentation can be found in the README on GitHub and on the Google Code pages.  If you use SwfObject 2.3, you can have high confidence that your content will load appropriately with all modern browsers.

If you are interested in learning more, make sure to check out the remainder of the article after the break.

Huge thanks to Peter Grandmaison and Jeromie Clark for their encyclopedic knowledge and guidance putting this post together.

classid is no longer supported

Reference: classid attribute | classid property

Since Internet Explorer 3.0 introduced support for Active-X controls, the preferred way to create an instance of the Flash Player in Internet Explorer has been to use an <object> tag with a classid set to “clsid:D27CDB6E-AE6D-11cf-96B8-444553540000”.

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="550" height="400">
    <param name="movie" value="sample.swf" />

Internet Explorer 11 and Edge no longer support the classid attribute.  If your code looks similar to the code above (you can simply search your code for the classid), then your page will no longer work in Internet Explorer 11 or Edge.  Instead, you should use the type attribute set to “application/x-shockwave-flash” as illustrated below.

<object type="application/x-shockwave-flash" data="sample.swf" width="550" height="400">
    <param name="movie" value="sample.swf"/>

Conditional Comments are no longer supported

Reference: About conditional comments

For instance,

<!--[if IE 8]>
<p>Hidden Form.</p>

<![if lt IE 8]>
<p>Revealed Form.</p>

Internet Explorer 5 through 9, would include the code in the page only when the expression in the comment was true.

Other browsers did not support conditional compile, so the code in the first example is excluded from the page because it is a part of a block comment, and the code in the second example is included in the page.

Internet Explorer 10 stopped supporting conditional comments so the following (previously recommended code pattern) results in the creation of two <object> elements instead of one:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400" id="movie_name" align="middle">
   <param name="movie" value="movie_name.swf"/>
   <!--[if !IE]>-->
   <object type="application/x-shockwave-flash" data="movie_name.swf" width="550" height="400">
      <param name="movie" value="movie_name.swf"/>
      <a href="http://www.adobe.com/go/getflash">
         <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/>
   <!--[if !IE]>-->

ExternalInterface does not work

Reference: ExternalInterface – AS3

Actually, ExternalInterface does work correctly in Internet Explorer 11 and Edge, but other changes often break ExternalInterface as ExternalInterface has player type specific behavior. The Active-X control requires the corresponding element to specify an identifier using the id attribute. The NPAPI plugin does not require an identifier for ExternalInterface to work, so it’s common to see:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400" id="movie_name" align="middle">
    <param name="movie" value="movie_name.swf"/> 
    <!--[if !IE]>-->
    <object type="application/x-shockwave-flash" data="movie_name.swf" width="550" height="400">
        <param name="movie" value="movie_name.swf"/>
    <a href="http://www.adobe.com/go/getflash">
        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/>
    <!--[if !IE]>-->

where the outer <object> tag with attributes classid and id is expected to construct the control instance in Internet Explorer, and the inner <object> tag which omits the id is expected to construct the plugin instance in other browsers. But Internet Explorer 11 no longer supports classid, so it will unexpectedly construct the instance of the control using the inner <object> tag which omits the id. The solution is to simplify the source

<object type="application/x-shockwave-flash" data="movie_name.swf" width="550" height="400" name="movie_name" id="movie_name" align="middle">
    <param name="movie" value="movie_name.swf"/> 
    <a href="http://www.adobe.com/go/getflash">
        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player"/>

All browsers support constructing flash using an <object> tag with a type attribute. Note the <object> tag intentionally specifies the name and id attributes with the same value – the control uses theid as the element’s identifier, and the plugin uses the name, so to ensure cross browser support, it’s important to provide both.

User Agent has changed

Reference: Compatibility changes in IE11

<!-- IE 10 -->
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
<!-- IE 11 -->
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
<!-- Edge -->
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240

NOTE: Internet Explorer 8 introduced Trident into the user agent

NOTE: All versions prior to Internet Explorer 11 included MSIE in the user agent.



Another way to detect IE versus non-IE is navigator.appName, which returns “Netscape” in IE 11, and “Microsoft Internet Explorer” in IE 10, so it’s common to see

isInternetExplorer = navigator.appName && navigator.appName.indexOf("Microsoft") != -1;

<!-- IE 10 : navigator.appName == "Microsoft Internet Explorer" -->
assert(isInternetExplorer == true)

<!-- IE 11 : navigator.appName == "Netscape" -->
assert(isInternetExplorer == false)


Reference: Cross-browser plugin detection

For instance,

<!-- isIE is false in Internet Explorer 11, but true for all prior versions -->
if (ActiveXObject) { isIE = true; }
<!-- succeeds on all Internet Explorers when flash is installed -->
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); }

window.ActiveXObject() is a factory method for controls. Internet Explorer 11 and Edge still allow scripts to invoke the function, but it has been hidden from the DOM, so isIE would be false in Internet Explorer 11.


Reference: fscommand() – AS3

FSCommand() allows a movie to communicate with the browser. Web pages are encouraged to use ExternalInterface instead of FSCommand(). The implementation of FSCommand() is player type specific. The NPAPI plugin will respond to FSCommand by invoking a global function in the DOM, where the function’s name is a concatenation of the name of the player instance and _DoFSCommand, such as

function example_DoFSCommand(command, args) {
    // javascript function called in response to fscommand()
    // in script in the player instance named "example"
<object type="application/x-shockwave-flash" data="example.swf" name="example" id="example" width="550" height="400">
    <param name="movie" value="example.swf"/>

The Active-X Control, in Internet Explorer 10 or earlier, will fire an fscommand() DOM event, so the page must add an event handler. For cross browser support, the event handler can call the above global function, such as

<script type="text/javascript" event="FSCommand(command,args)" for="example">
    example_DoFSCommand(command, args);

Starting with Internet Explorer 11 and now with Edge, the control will invoke the same callback used by the plugin.

An example of this breaking in Internet Explorer 11 (and 10) is the SWFOBJECT 2.2 test suite test for FSCommand:


The control is dispatch the fscommand event, but when you review the HTML you can see the event handler isn’t getting registered because it’s wrapped in conditional comments:
<!--[if IE]>
<script type="text/javascript" event="FSCommand(command,args)" for="myCom">
myCom_DoFSCommand(command, args);
Because conditional comments are no longer supported, the event handler is not registered, so the callback is not invoked.

Hidden <div>’s

Many modern sites use a pattern of embedding Flash content into a hidden <div>; however, Internet Explorer is unique in that it will not initialize Flash Player in a <div> that is not visible.  The outcome is that Flash content placed into a hidden <div> will never load in IE or Edge.  To work around this unique behavior, common JavaScript patterns have emerged that set the container div to visible when the content is loaded by Internet Explorer.

Internet Explorer versions 11 and higher supply a User-Agent string that indicates a Mozilla-based browser is being used.  As current versions of many popular JavaScript libraries depend on the User-Agent to identify whether or not Internet Explorer is in-use, this change has broken fundamental assumptions made in many of the common JavaScript patterns used to embed Flash-Based content on modern sites.
Until popular libraries can develop new methods to accurately identify Internet Explorer 11 and higher, content developers are advised to avoid using hidden divs (i.e. <div style=”visibility:hidden”>) when embedding Flash content into a page, or to ensure through JavaScript that the div is always set to visible prior to Flash content being loaded into it.

A very simple modification to existing jQuery code that loads a Flash-based YouTube video into .previewhiddencontainer might look like this

<script type="text/javascript" charset="utf-8">
 $(function() {
 // Pre-IE11 behavior 
 // if ($.browser.msie) {
 // $(".previewhiddencontainer").css("visibility", "visible");
 // }
 // IE11 compatibility - always set to visible
 $(".previewhiddencontainer").css("visibility", "visible");
 window.onYouTubePlayerReady = function(playerid) {
 setTimeout(function() {
 $(".previewhiddencontainer").css("visibility", "visible");
 }, 1000);
 var p = document.getElementById("youTubePlayer");
 + "xxxxxxxxxxx"
 + "&enablejsapi=1&playerapiid=player1&rel=0&hd=1&showinfo=0",


Historically, the HTML and javascript used with the control in Internet Explorer was different enough from the HTML and javascript used with the plugin in other browsers, that web pages would detect whether the browser was control-based or plugin-based, so it could run control-only or plugin-only code.

From a javascript only perspective, Internet Explorer 11 and Edge are consistent with other HTML5 browsers, so such IE specific code is no longer needed.  Many of the changes documented above are designed to cause pages to detect Internet Explorer 11 and Edge as plugin-based browsers.

However, sometimes, control-only javascript in the page matches control-only code in a flash movie, so a mismatch occurs (and the site breaks) if the page detects plugin-based and the movie detects control-based.  For instance, the page might search the user agent for MSIE, and the movie might use (Capabilities.playerType == “ActiveX“).

As the changes in Internet Explorer 11 and Edge intentionally cause existing scripts to mislabel the browser as plugin based, it’s worth reviewing any control or plugin specific code on your site.  Similarly, if your SWF contains any control or plugin specific ActionScript, for instance, using Capabilities.playerType to detect the player type, you should review this code to determine whether it still works as expected in Internet Explorer 11 and Edge.


2 Responses to Flash Player guidance for Internet Explorer 11 and Microsoft Edge

  1. Katia Gomez says:

    Hi. We are an educational content developer comapny in Brazil, having over 270 courses developed in Flash Player. We are looking to develop an APK for mobile. Do we need Adobe Air for this? Do you have any partners that could help us develop this? Thanks

  2. This was great knowledge to know about my IE 11 settings. Thank you so much on the information you shared with me.