Na navigaci | Klávesové zkratky

How to correctly insert a Flash into XHTML

Although flash is the most spread active element of webpages, a lot of designers still don't know the correct way to insert it into HTML document.. The standard concept, advertised by Macromedia is absolutely unusable.

Just a reminder:

<object
  classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
  width="550" height="400">
  ...
  <param name="movie" value="movie.swf" />
  <param name="quality" value="high" />
  ...
  <embed src="movie.swf" quality="high" bgcolor="#ffffff" width="550" height="400"
    type="application/x-shockwave-flash"
    pluginspage="http://www.macromedia.com/go/getflashplayer">
  </embed>
</object>

Attributes of <object> element are subordinated to needs of Internet Explorer and they won't work in other browsers. Other browser use element <embed> for the same purpose, but it isn't listed in HTML or XHTML specifications. The code is therefore not valid and is full of proprieatary hacks.

The biggest problem is in the fact, that it's not possible to provide alternative content which will be displayed to users who don't have flash player (ca. 10%)

Looking for solution

What are the requirements?

  • it must work in all major browsers
  • it must display alternative content if the Flash plugin is missing
  • it must not rely on JavaScript
  • it must be compatible with Eolas workaround trick

Surely we have to get rid of the <embed> element. By this simplification we'll get distinct space for alternative content. The script will now look like this (example)

<object
  classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  codebase="http://fpdownload.macromedia.com..."
  width="550" height="400">

  <param name="movie" value="movie.swf" />
  <param name="loop" value="false" />
  ...
  <p>This is alternative content</p>

</object>

The presented solution will work in IE and Opera and if Flash is uninstalled the alternative content is correctly displayed.

However, script still uses attributes of element <object> contrary to specification and therefore Mozilla won't display Flash (it will display alternative content). Ok, let's get it into accordance.

We'll remove attributes classid and codebase and replace it by correct MIME type and data containing path to Flash file. Parameter movie is then becoming dispensable. After the changes script will look like this (example):

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

  <param name="loop" value="false" />
  <param name="movie" value="movie.swf" />
  ...
  <p>This is alternative content</p>
</object>

That will work in Mozilla and also in Opera. In Internet Explorer it won't. If we returned the above mentioned parameter movie, IE would have displayed the Flash (“example”::http://knowhow.davidgrudl.com/…e-W3C-2.html), but with unwelcome limitation – the progressive download won't work. Flash will be displayed only after it's file completely downloaded.

Drew McLellan took the same considerations back in 2002 when he came up with a method called Flash Satay, which solved the problem of lacking progressive download by using of additional container Flash. Because of that it has solid problems with accesibility (which doesn't bug me that much) and it also won't work with Eolas workaround trick. And that is indeed a major glitch.

How to combine the two scripts?

We have two notations, varying just in a detail. I've tried number of ways how to put them together. In all of them I met bigger or smaller difficulties. In one case Mozilla doesn't display alternative version, in other IE has problems, etc.

The best thing I could come up with was to completely avoid combining of those two scripts. Inserting both of them to HTML and differentiate them by using of conditional comments.

Code written for IE will be wrapped like this:

<!--[if IE]>
HTML code only for IE
<![endif]-->

But how to assign a code dedicated to other browsers? For this purpose there exists a negated conditional comment, which is unfortunatelly not valid. We will solve this problem by using of a trick (explanation) and rewrite the comment to this final valid form:

<!--[if !IE]> -->
HTML code for all except of IE
<!-- <![endif]-->

Final Solution

The complete code will then look like this (example + validator):

<!--[if !IE]> -->
<object type="application/x-shockwave-flash"
  data="movie.swf" width="300" height="135">
<!-- <![endif]-->

<!--[if IE]>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"
  width="300" height="135">
  <param name="movie" value="movie.swf" />
<!--><!--dgx-->
  <param name="loop" value="true" />
  <param name="menu" value="false" />

  <p>This is <b>alternative</b> content.</p>
</object>
<!-- <![endif]-->

Maybe it's not a brilliantly elegant solution, but it's only truly functional solution that I have found.

  • it's valid
  • it's functional in all browsers that I know
  • it always show alternative content if the plugin is missing
  • it can be combined with Eolas workaround trick
  • it doesn't require javascript
  • tags <param> are not doubled

note: because of Opera, don't use <param name="wmode" value="transparent" /> or opaque

Kindly translated by creamd

Komentáře

  1. coda http://coda.co.za #1

    avatar

    SWFObject

    …Javascript Flash Player detection and embed script

    před 10 lety | reagoval [2] David Grudl
  2. David Grudl http://davidgrudl.com #2

    avatar

    #1 coda, it is not hard to create JavaScript based solution, it's hard to create non-JavaScript one.

    před 10 lety
  3. Geoff http://blog.deconcept.com #3

    avatar

    There are reasons to use Javascript, and there was recently a very large discussion about the topic here:

    http://blog.deconcept.com/…s-yes-again/

    před 10 lety
  4. Michael Bernstein http://michaelbernstein.com #4

    avatar

    What about Safari?

    před 10 lety
  5. minghong http://minghong.f2g.net/ #5

    avatar

    For me, I use the following HTML:

    <object type="application/x-shockwave-flash" data="example.swf"
      width="640" height="480">
      <param name="movie" value="example.swf">
      <param name="wmode" value="transparent">
    
      <img src="example.png" alt="Alternate content if Flash is not supported" width="640" height="480">
    </object>

    Then the following IE-only JScript is inserted using conditional comment:

    // Hide objects to prevent flickering when recreating the objects
    document.write( '<style type="text/css" id="ieflashfix">' );
    document.write( 'object { display: none }' );
    document.write( '</style>' );
    
    // Recreate and reveal the hidden objects
    window.attachEvent( "onload", function()
    {
        // Recreate the objects
        var objects = document.getElementsByTagName( "object" );
        for ( var i = 0; i < objects.length; i++ )
        {
            var object = objects.item(i);
    
            // Fix flash object
            if ( object.type == "application/x-shockwave-flash" )
            {
                if ( object.getAttribute("data") )
                {
                    object.removeAttribute( "data" );
                }
                object.outerHTML = object.outerHTML;
            }
        }
    
        // Reveal the objects by removing the stylesheet created by document.write
        var stylesheet = document.getElementById("ieflashfix");
        stylesheet.parentNode.removeChild( stylesheet );
    } );
    před 10 lety
  6. myself #6

    před 10 lety
  7. Chris #7

    what about
    http://alistapart.com/…s/flashsatay

    That was mentioned in the article…

    před 10 lety
  8. Ian Hickson http://ln.hixie.ch/ #8

    avatar
    před 10 lety
  9. mrmatt #9

    avatar

    What's this line for? How does it work?!

    <!--><!---->

    Why not simply replace that with this:

    <!-- <![endif]-->

    Confused!

    před 10 lety
  10. Gordan http://www.index.hr #10

    avatar

    Doesnt work when using flashvars. Flashvars are empty in object[i].outerHTML.

    před 9 lety
  11. Kim solomon #11

    avatar

    The latest version of Dreamweaver CS3 does a pretty good job of making the flash compatible across all browsers and showing alternate text. Is that not a good enough solution for this. Also another article on <a href="http://www.interface.co.in/t-website-design-part1.aspx">xhtml, css coding for compliance.

    před 9 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.