Web standards compliant Javascript Quicktime detect and embed

Due to the popularity of my FlashObject embed, I decided to create a helpful little Javascript file for doing detection and embedding QuickTime movies.

Embedding QuickTime movies in websites presents many of the same problems as embedding Flash. Since QuickTime relies on a third party plugin, your users will need to have this plugin installed before they can view your content. If they don’t have the plugin, they will be greeted by either an AcitveX install window (Internet Explorer) or an ugly ‘broken plugin’ image on other browsers. I prefer using Javascript to detect the presence of plugins because it gives you more control over what your users see when they visit your site. Most web browsers handle plugin installs terribly, often giving the user cryptic looking placeholders (broken puzzle pieces) or strange sounding legal notices on ActiveX install dialogs (of which people may have been trained to always say ‘no’ to since the same dialog box will often install spyware).

Anyway, enough chit-chat. On to the Javascript:

To use the QTObject embed, you simply create a new QTObject, add the parameters you want, and then write it to the page. The script will check to see whether the QuickTime plugin is available and write the embed code to the page or the alternate content if the user doesn’t have the required plugin. Here is an example of what a simple movie embed would look like (I used a fun little video I found floating around the Internet as a sample movie, but it can be any .jpg, .gif, .png, or even another .mov file.): (View Example)

var myQTObject = new QTObject("bushuncensored.mov", "bushfinger", "320", "255");
myQTObject.addParam("autostart", "false");
myQTObject.write();

In this example the ‘myQTObject.addParam()‘ isn’t needed, but it’s a nice addition that will keep the movie from starting before the user figures out what they are looking at.

The parameters from left to right are the path to the mov file, the ID of the mov file, the width, and then the height of the file. If you are showing the QuickTime controls, you need to add 15 pixels or so to the height of the movie or the controls will be pushed down and the user won’t be able to see them.

If you want to do some more advanced embedding, such as the method Apple uses on their QuickTime site, your code would look something like this: (View Example)

var myQTObject = new QTObject("bushplaceholder.jpg", "bushfinger", "320", "255");
myQTObject.addParam("href", "bushuncensored.mov");
myQTObject.addParam("target", "myself");
myQTObject.addParam("controller", "false");
myQTObject.write();

This uses a few extra parameters that allow you to use a placeholder image that will load in the place of your movie until the user clicks on it. Your movie would then load in the place of the image and start when it has loaded enough to start playing. You simply replace the mov source from the first example with your placeholder image (you remembered to add 15 pixels to the height of the image to account for the QuickTime controls, right?) and then an extra few parameters to tell the QuickTime embed where to find the real movie, the target QuickTime object, and finally telling it to hide the controls before the real movie loads.

There is also the option of redirecting the user to another page if there is no QuickTime plugin found by using this code: myQTObject.redirect = "upgradepage.html";, and there is a built in bypass of the detect script by including detectqt=false in the query string when you request the page. This link is included in the ‘upgrade’ notice so if for some reason a user has QuickTime installed but the Javascript detect fails, they can still attempt to view the QuickTime content.

Also, be sure you use this in combination with <noscript> tags just in case some of your users have Javascript disabled.

That’s it! Since it uses Javascript to create the embed and object tags, it will validate as XHTML 1.0 (strict or transitional). Please note that it will not work with pages sent as application/xhtml+xml since it uses innerHTML and document.write(). Another note: I’m not checking for the version of the QuickTime plugin installed, and I couldn’t find any older QuickTime players for testing, so I’m not sure how this will treat users who are using QuickTime 4 to view content that requires QuickTime 6. I seem to remember QuickTime having an auto-update feature or some built in notification if you need to upgrade, so I’m not too worried about it, but if anyone has some experience in this area, I’d love to hear how this embed method behaves under those circumstances.

I’ve tested this on IE 6, 5.0, 5.5 on PC, Firefox on Mac and PC, and Opera and Safari on Mac. It has worked great every time, but everyone knows there can always be little bugs that pop up, so if anyone finds something wrong with the code, let me know.

Download source and example files (1.09MB)

UPDATE (02-11-2005): Just fixed a few bugs – one that was giving problems if the user didin’t have QuickTime installed on Internet Explorer for PC, and adjusted the default Alternate text.

UPDATE (02-16-2005): Not sure how something like this slipped past, but Thiago found a little bug in the VB Script that was giving some problems in IE on a PC. The files have all been updated.

100% height and 100% width XHTML Flash embed

I’ve been asked this question a few times in the last couple of months, so I thought I would put together an example page to show how you can get Flash content to stretch to 100 percent height and width without using tables.

View example: 100% width and height stretched Flash embed.

It’s actually pretty simple. Here’s some of the CSS I used:

/* hide from ie5 mac \*/
html {
  height: 100%;
  overflow: hidden;
}
#flashcontent {
  height: 100%;
}
/* end hide */
body {
  height: 100%;
  margin: 0;
  padding: 0;
  background-color: #eee;
}

Setting the html tag to 100% height and then placing the Flash movie inside a div that is also set to 100% height does the trick.

Notice the overflow: hidden on the html element since IE will show the scrollbar even if the page doesn’t need to scroll. This line will force IE to hide any content that is outside of the browser window, and therefore hide the scrollbar as well.

To embed the Flash movie, I used my FlashObject Javascript embed so the page will validate and I have access to all the various Flash parameters I might need to pass to the Flash movie.

UPDATE (01-05-2005): Someone pointed out a bug with this in IE 5 on Macintosh, so I’ve updated the CSS a bit to make it work. Current verified working browsers are: IE 6 (PC), IE 5 (Mac), Safari, Firefox (PC, Mac), Mozilla (PC, Mac), Opera 7.54 (Mac).

If you have other browsers available for testing I would love to know if this displays properly or not. I’m mainly interested in IE 5 and 5.5 on a PC.

UPDATE (1-17-05): Tested in IE 5.01 sp2 and IE 5.5 sp2 on a pc today, and it works great.

iVillage Redesign

For some reason nobody told me that the iVillage redesign that we did was partially launched last month.

This was one of the first projects I worked on when I moved to New York. We decided on a CSS layout using XHTML 1.0 transitional (sent as text/html), with some Flash peppered around. Right now only the entertainment section is using the new design, with the other sections to follow as their internal team takes our template and adapts the content in the other sections. Unfortunately the site doesn’t validate because of one little error(!) that I’ll be passing along to their internal team along with a few small visual errors to fix.

It uses a similar method to the suckerfish dropdowns for the flyout menus on the left navigation, and some basic CSS rollovers for the main navigaion tabs at the top.

I would have liked to use my FlashObject embed for the Flash content, but this was handed over to their internal team way before I had even thought it up, so it uses generic Javascript to detect and embed the Flash movies.

UPDATE (12-22-2004): Looks like the one validation error was in some content that has now rotated off of the homepage, so now it validates!

UPDATE (01-31-2005): The whole site went live this week.

Standardizing Flash

Tommy over at Autistic Cuckoo has posted a little writeup on what’s next for Web Standards. Among his list of things is this:

[there are still many sites that] require third-party products such as Flash to work

I think this point should be looked at from the other side of the fence. Flash is not going away. It’s way way too popular and useful for too many websites.

Once you think of it like this, the problem becomes how tough it is to use Flash in a way that doesn’t invalidate your documents, which is where I think much more fucus needs to go these days.

Standardize the browser plugin architecture and I bet you’ll see way more XHTML valid Flash websites.

Why it’s OK to send XHTML as text/html

I was recently dragged in to an argument about whether or not it’s ok to send XHTML files with a mime type of text/html instead of application/xhtml+xml.

It seems that there are a few people spreading the word that sending XHTML documents as text/html is not only improper, but downright bad for you (gasp!). The basic argument goes something like this:

Dude[ette] sends XHTML document as text/html instead of application/xhtml+xml and therefore is gaining no advantage over plain old HTML 4.01. Since XHTML ‘should’ be sent as application/xhtml+xml, doing it any other way is wrong and you will burn in hell. Instead you should use HTML 4.01 because more browsers understand it, and when the time comes to switch, you can just use HTML tidy or make the small changes your pages need by hand.

Ok, I added the ‘burn in hell’ part, but you get the general idea.

Now I’m not going to go into why you should use application/xhtml+xml or all the benefits and differences between that and text/html. Instead, I’m going to let you read up on the subject yourself, and then tell you why it’s quite acceptable to keep on using text/html for the time being.

All of these links are full of excellent information and everyone building XHTML websites should know this whether they agree with them or not. Go ahead and take a few moments to read them. I’ll wait here.

Ok. Wasn’t that fun? Now here are some reasons why sending your XHTML pages as text/html is just fine. It is important to realize that the real argument here is not whether they should be sent as application/xhtml+xml or not, but what to serve as an alternative to user agents that can’t support it, such as IE.

1) XHTML 1.0 is like a gateway drug. It’s not HTML, and it’s not quite XML, but it’s a nice middle ground. It teaches you to close your tags, use lowercase attributes, always quote your attributes, never ‘minimize’ your attributes, and a few more. All of these are outlined here: The difference between XHTML 1 and HTML 4. This is a great benifit in that it teaches developers to follow stricter rules when building pages, and when the time eventually comes when they need to switch to application/xhtml+xml, there will be fewer changes to worry about than with HTML 4.

2) The XHTML standard allows you to use text/html. A short excerpt:

XHTML Documents which follow the guidelines set forth in Appendix C, “HTML Compatibility Guidelines” may be labeled with the Internet Media Type “text/html” [RFC2854], as they are compatible with most HTML browsers.

So the way I see things is that sending XHTML as text/html isn’t a bad thing at all. Using XHTML teaches developers to write well-formed documents, and teaches them the basics of XML, which will be more and more valuable as we progress from HTML to XML documents on the web. I think it’s important that people know the differences when sending documents with different mime types, but discouraging the use of XHTML sent as text/html doesn’t help anyone, and telling them there are no advantages at all is misleading.

Other reading:

UPDATE (11-10-2004): I just came across this post about content negotiation and saw an excellent conversation in the comments about converting your XHTML to HTML and the issues you will encounter.

One of the readers makes this point:

Your situation is different, though. I totally agree that XHTML should be served as application/xhtml+xml to browsers that support it. With respect to IE, you have some choices.

You could just serve it the XHTML content as text/html. Provided you’ve authored it in HTML-compatibility mode, IE will handle that perfectly well (or, at least, no worse than it handles HTML4).

Alternatively, you could decide, as you apparently have done, to serve IE HTML4, using a conversion that

1) only works with XHTML written in compatibility mode

2) runs the risk of seriously munging your text. (This is, after all, a weblog about web design!)

What’s the benefit of doing this instead of just sending IE the unaltered XHTML document (as text/html)?

And the response:

Nothing, probably. I’m reworking the “CMS” at the moment, and if I ever finish it, I will use a better system for converting to HTML. In fact, since XHTML is currently useless unless you actually need it (like your blog), I’m thinking about serving HTML 4.01 Strict to all. I’ll still store the posts as XML, though, for various reasons, so some kind of rewriting will be necessary.

So it seems to me that the optimal solution for most websites these days would be this:

  1. Author your pages as XHTML 1.0 strict or transitional in ‘compatibility mode
  2. Use content negotiation to send application/xhtml+xml pages to user agents that favor XHTML content
  3. For user agents that don’t like application/xhtml+xml, send them ‘compatible’ XHTML 1.0 as text/html

This way user agents that can handle XHTML get it, and if the user agent doesn’t understand application/xhtml+xml, you will have a very minimal amount of work on the server side to convert your XML content to ‘compatible’ XHTML.