Introduction to Cross-Browser, Cross-Platform, Backwardly Compatible JavaScript and Dynamic HTML
By Eric Krock
Technology Evangelist
Do you want to write Dynamic HTML that runs
on both Navigator 4.0 and Internet Explorer 4.0? This TechNote gives an overview
of the tools, TechNotes, articles, and other resources on the Netscape
site and elsewhere which will help you build Dynamic HTML pages which reach
the widest possible audience without breaking on older browsers.
CONTENTS
WHY CROSS-BROWSER DYNAMIC HTML?
The genius of HTML was that it could be edited
and viewed on any computer in the world and transmitted across the network
transparently and painlessly. This liberated information from the chains
which had bound it to hard drives and LANs, enabling anyone anywhere to
see anything anywhere else.
The drawback of HTML was that it was static
and boring. Dynamic HTML should bring HTML pages to life on any DHTML-capable
browser while in the spirit of HTML remaining viewable in some form by
any client on any computer. A text-only browser like Lynx will never display
animations, but well designed Dynamic HTML will (in addition to being fully
functional on both Internet Explorer 4.0 and Navigator 4.0) degrade gracefully so that the content
is still viewable on older versions of the browsers and on text-only browsers
for disabled accessibility and indexing by robots.
This means that the challenge today for
web designers is to exploit the power of Dynamic HTML without chaining
their site to any single operating system or browser and without locking
out the disabled or users of earlier browsers and older operating systems.
Cross-platform and cross-browser support
are both critical because content providers are striving to reach the largest
possible audience and corporations want to link tightly to all their customers
and suppliers over the extranet. In both situations, you don't want to
lock out potential viewers, customers, advertising dollars, and sales for
technical reasons like OS version or browser vendor. Your success depends
upon reaching everyone. Who would buy a TV ad that could only be seen by
20-40% of the viewers? That's exactly what happens if you restrict your
content to a particular OS or browser.
Building cross-platform DHTML is only easy
to the extent that each browser provides a consistent foundation to build
upon across platforms. For each browser, you need to figure out what functionality
can be used across all the platforms you're trying to reach. Once you've
figured out what functionality each browser will reliably provide across
all of your target platforms (each browser's cross-platform functionality)
then you need to figure out how to build your site across the two browsers
(the cross-browser functionality).
Both Netscape and Microsoft have committed
to come into full compliance with the recently-released HTML 4.0 specification
and the still-under-development W3C DOM. So one approach for building cross-browser
DHTML would be to wait until consensus is reached and standards are finalized
and fully implemented. However, most people want to attract more
viewers and customers today, so the best approach for now is to build today
upon the browsers' common functionality and to make sure you leverage as
much of the standard functionality as is currently available.
WHAT IS CROSS-BROWSER DHTML?
Netscape and Microsoft each have their own
definition of Dynamic HTML. Cross-Browser DHTML is the subset of DHTML
functionality which can be used compatibly across platforms and across
Navigator 4.0 and Internet Explorer 4.0. (If you can achieve the same result
in both browsers by conditionally using two techniques, that counts!) Cross-Browser
DHTML includes:
- shared support for Cascading Style Sheets, level 1 (CSS1)
- shared support for Cascading Style Sheets Positioning (CSSP)
- shared JavaScript support
- Document Object Model functionality which is common to the two browsers
- event model functionality which is common to the two browsers
- downloadable font resources (also known as Dynamic Fonts)
- full screen mode
Anything which is browser or platform dependent
is not cross-browser DHTML. In particular, cross-browser DHTML developers
should avoid building pages which work in one browser but cause errors
in the other browser or in older browsers. The goal is to offer the same
functionality on both up-to-date browser versions and to degrade gracefully
for older browser versions.
What You Need To Know
This TechNote assumes the reader is familiar
with JavaScript,
Cascading Style Sheets,
level 1 (CSS1), Positioning
HTML Elements with Cascading Style Sheets (CSSP), and Netscape's JavaScript
Document
Object Model, which makes the formatting and positioning properties
of style sheets accessible from JavaScript.
THE PROBLEM
There are already enough web technology standards
to sink a battleship. The arsenal includes HTML 4.0, CSS1, CSSP, ECMA-262,
and the W3C DOM currently in development, not to mention newer specifications
like RDF, XML, CSS2, and every other three- and four-letter permutation
of ASCII.
With so many standards, why is compatibility
still and issue? For a detailed explanation of why there are differences
in cross-browser support for and implementation of HTML, CSS1, CSSP, JavaScript,
and the Document Object Model, see A
Web developer's guide to the newest cross-browser compatibility issues.
Here are some of the key sources of difficulty:
- No vendor has implemented every feature of many of the existing standards (e.g. HTML 4.0, CSS1, CSSP).
- Standards often leave room for differences in interpretation and implementation.
- Standards often include suggestions or recommendations which vendors are not required to comply with.
- Standards often permit vendors to add enhancements not defined by the standards.
- The standards definition and ratification process often lags behind the implementation of functionality by the vendors.
The practical approach for building applications is to study the standards, study each vendor's implementation, find the
common functionality, and build on top of that.
This TechNote focuses on client-side techniques
for achieving backward compatibility. It explains how to create a single
page which degrades gracefully for older browsers. However, you can also
address this problem on the server side by detecting the user's client
and delivering one of several pages that have been optimized for different
browsers and versions. If you are comfortable with both client-side and
server-side development, often a combination of the two approaches is most
efficient. To learn more about the differences between client-side and
server-side solutions to this problem, read Netscape's
Home Page--Part Two: Dynamic HTML and Older Browsers--What to Do?.
CSS1 SUPPORT
Cascading Style Sheets, level 1 (CSS1) makes
it possible to specify the formatting and style of HTML pages in a browser
and platform independent way. For more detail, see the tutorials indexed on Netscape's Dynamic
HTML Additional Resources Page or read the CSS1 specification on the
W3C site.
Neither Navigator 4.0 nor Internet Explorer
4 have implemented support for every feature of CSS1, and there are differences
in the degree of support for CSS1 across platforms.
The main point to remember is that if you would like to use a particular CSS1 property, you should first check whether
your target browsers support it on each target platform.
CSSP SUPPORT
CSSP markup makes it possible to declare HTML
elements to be absolutely or relatively positioned, to define their initial
position on the page, and to make the elements initially hidden or visible.
For more detail, read the Positioning HTML Elements With Cascading
Style Sheets specification on the W3C
site.
I am not aware of a rigorous, independent,
property-by-property comparison of Navigator 4.0 and Internet Explorer 4.0's support for CSSP similar
to WebReview.com's comparison of the browsers' CSS1 support. My personal
experience in cross-browser CSSP development has been that if you use absolute
positioning, define positions in pixels, position each element independently,
avoid element nesting, and test carefully, then you can achieve cross-browser
layouts which look the same or very similar. My own informal "safe" list
for cross-browser CSSP support for Navigator 4.0/Win32, Navigator 4.0/Mac, Navigator 4.0/UNIX, and
Internet Explorer 4.0/Win32 is the use of absolute positioning and pixel units for these
properties:
| Property |
Values |
| position |
absolute |
| left |
pixel units |
| top |
pixel units |
| width |
pixel units |
| height |
pixel units |
| clip |
pixel units |
| z-index |
positive integers |
| visibility |
inherit |
visible | hidden |
I'm not aware of any particular problems with cross-browser support for relative positioning. I just avoid it because
to me, it seems to be confusing and non-intuitive compared with the certainty of absolute positioning.
Keep in mind that cross-browser CSSP support
does not guarantee layouts which are pixel-for-pixel identical. (Although
graphic designers find this understandably disappointing, the reality is
that the CSSP standard was never intended to achieve a degree of fine layout
control equal to PostScript. Comparing the length of the PostScript and
CSSP specifications makes that clear.) As a result, there are sometimes
slight differences in positioning, borders, backgrounds, and so on. However,
the degree of cross-browser compatibility is sufficient to make possible
many practical applications, such as Netscape's Dynamic
HTML Presentation Template.
Know Your Client!
The key to building JavaScript and Dynamic
HTML that runs on both Navigator 4.0 and Internet Explorer 4.0 (and which degrades
gracefully for older browsers) is to detect the user's browser vendor
and version and then conditionally evaluate the correct JavaScript
for that browser. To determine the user's browser vendor (Netscape,
Microsoft, Opera, etc.) and version number (2.x, 3.x, 4.x, 5.x, etc.),
use the JavaScript browser-detect code in The
Ultimate JavaScript Client Sniffer. This freely downloadable sample
code defines an is object with boolean properties such as is.nav,
is.nav3, is.nav4,
is.nav4up, is.ie4up,
is.opera and version number
properties such as the integer is.major and
the float is.minor. You can
check these properties in your JavaScript code to determine which browser
the code is running on and then branch to evaluate the appropriate code
for that browser. When you write a version check in your code, be sure
to provide support for future releases. For example, use (is.major
>= 4) instead of (is.major
== 4), and use is.nav4up
and is.ie4up instead of is.nav4 and is.ie4. Otherwise, your
code will fall victim to the dreaded "V50 bug" (a distant cousin of the
"Y2K bug") and stop working when the browser's version number changes from
4 to 5!
BACKWARD COMPATIBILITY
In an ideal world, every user would have a
copy of the latest version of Netscape Communicator installed on their
desktop within a day of its release, and all features would be fully enabled.
In the real world, providing backward compatibility for older versions,
non-JavaScript browsers, and browsers with JavaScript turned off is important
for the following reasons:
- Many users have not yet upgraded to the latest version and are still using a previous version of Navigator or Internet Explorer 4.0.
- Some users are browsing from behind firewalls which disable JavaScript.
- Users with disabilities (particularly the non-sighted) may be using text-only browsers.
Non-JavaScript Browsers, Text Only Browsers,
and Browsers with JavaScript Turned Off
To degrade gracefully for non-JavaScript and
text-only browsers, be sure to enclose the content of STYLE and SCRIPT
tags within HTML comments so it is ignored rather than displayed onscreen
as content. Here are examples of backwardly-compatible commenting:
Of course, if the STYLE or SCRIPT tag is a
link to an external file, no comment is necessary as non-JavaScript and
non-CSS browsers will ignore both the tag and the external file it links
to:
Older Versions of JavaScript-Enabled Browsers
To prevent older browsers with earlier versions
of JavaScript from loading newer JavaScript they won't be able to understand,
the SCRIPT tag has a LANGUAGE attribute with which you can specify what
version of JavaScript the code is using. This table shows which tags will
be loaded by which browsers:
| Tag |
Loaded by: |
| <SCRIPT> |
all JavaScript browsers |
| <SCRIPT LANGUAGE="JavaScript"> |
all JavaScript browsers |
| <SCRIPT LANGUAGE="JavaScript1.1"> |
Nav3+, IE4+ |
| <SCRIPT LANGUAGE="JavaScript1.2"> |
Nav4+, IE4+ |
| <SCRIPT LANGUAGE="JavaScript1.1" SRC=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fdynhtml%2Fxbdhtml%2Ffoo.js&y=1999> |
Nav3+, IE4+ |
| <SCRIPT LANGUAGE="JavaScript1.2" SRC=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fdynhtml%2Fxbdhtml%2Ffoo.js&y=1999> |
Nav3+, IE4+ |
This approach works pretty well, with one
exception: Navigator 3 has a known bug which causes it to load external
JavaScript files (files linked to by a SRC= /old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fdynhtml%2Fxbdhtml%2Fattribute%29&y=1999 which have LANGUAGE
attribute set to "JavaScript1.2", even though Navigator 3 should ignore
those files.
The basic workaround for this bug is as
follows: within the external JavaScript 1.2 file, enclose the JavaScript
1.2-specific statements within an explicit browser version check, so that
the JavaScript 1.2-specific statements are parsed by Navigator 3
but only executed on Navigator 4.0 or later. Netscape's Dynamic
HTML Presentation Template includes an example of using this workaround:
|
// Workaround for Nav3.x bug in which JavaScript files
// with <SCRIPT LANGUAGE="JavaScript1.2" SRC=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fdynhtml%2Fxbdhtml%2F...&y=1999> are
// loaded, even though they should be ignored.
// Make sure this code is only executed by 4.x and later.
if (parseInt(navigator.appVersion) > 3) {
if (is.nav4up) document.captureEvents(Event.KEYPRESS);
document.onkeypress = handleKeys;
} // end of Nav4+ only if
|
This workaround itself has one problem: if
the external JavaScript 1.2 file contains certain JavaScript 1.2-specific
tokens (such as the switch
statement or regular expression literals like /a*bc+/),
then the Navigator 3 parser will generate JavaScript errors, even
though the code is only being parsed, not executed, on Navigator 3. If
you have JavaScript 1.2 code which includes such tokens, there are three
ways to avoid triggering Navigator 3 parser errors:
- Take the JavaScript 1.2 code which includes
that token out of the external file and place it in an inline JavaScript
SCRIPT embedded within the HTML page. (Nav3 only loads external JavaScript
1.2 files which are linked to by SRC=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fdocs%2Ftechnote%2Fdynhtml%2Fxbdhtml%2F%2C&y=1999 not inline scripts within the HTML
file itself.)
- Create separate paths through your site so
that Navigator 3 is never allowed to open that page. (For example, you
could dynamically write the link to the JavaScript 1.2 page, and only write
out the link if the user is using Navigator 4.0 or later.)
- Modify the code to avoid using the JavaScript
1.2-specific token which is causing the error. (For example, use if instead
of switch and string parsing instead of regular expressions.)
BROWSER-DEPENDENT CONTENT
When bridging the differences between various browsers and versions, it often helps to dynamically generate
some of your markup using document.write() statements after checking which
browser is viewing the page. This allows the page to display different,
optimized markup for each browser and version number. The TechNote on Setting
CSSP Properties from JavaScript explains Three
Approaches for Cross-Browser DHTML Markup and provides an API
with functions for dynamically generating DHTML markup as well as Dynamically Generating Other Browser-Dependent Content.
SETTING CSS1 PROPERTIES FROM JAVASCRIPT
As powerful and handy as they are, style sheets
do have a basic limitation: they are static and hard-coded. They cannot
conditionally or intelligently format a page. For that, you must set CSS1
properties from JavaScript via the Document Object Model.
Remember this rule of thumb: "What you
can do with CSS (that is, CSS1 and CSSP), do with CSS. What you can't do
with CSS, do with JavaScript via the Document Object Model." In other words:
if the value is static and never need change, set it from CSS. If the value
is conditional or needs to be set dynamically, set it from JavaScript.
To save you time when developing cross-browser
DHTML pages, Netscape has provided a cross-browser DHTML TechNote on
Setting CSS1 Properties From JavaScript. The TechNote includes a
JavaScript code generator which automatically generates JavaScript code that sets
CSS1 properties and works on both Navigator 4.0 and Internet Explorer 4.0.
SETTING CSSP PROPERTIES FROM JAVASCRIPT
Setting CSSP properties from JavaScript makes
it possible to dynamically move, hide, and show HTML elements as well as
change their background colors and background images.
Navigator 4.0 and Internet Explorer 4.0 have
different Document Object Models, so you must use different JavaScript
code to set CSSP properties on Navigator 4.0 and Internet Explorer 4.0. Danny
Goodman has written an excellent article in View Source explaining the
differences between the two browsers' DOM models for CSSP properties. I
won't repeat its contents here, so read JavaScript
Apostle: CSS-Positioning -- The Dynamic HTML Neutral Zone if you aren't familiar
with these differences already. As Danny's article explains, the best way
to bridge the DOM differences is to define a cross-browser Application
Programming Interface (API); that's just a fancy name for a set of functions
which you can call on both browsers to do commonly-used operations like
getting an element, hiding it, showing it, moving it, and so on. Each function
detects the user's browser and then evaluates the correct JavaScript code
to perform the operation on that browser.
To save you the trouble of defining your
own cross-browser DHTML API, Netscape has provided a TechNote on Setting
CSSP Properties from JavaScript on Navigator 4.0 and Internet Explorer 4.0. The TechNote includes
a freely downloadable and reusable cross-browser DHTML API for setting
basic CSSP properties. This API is designed to be usable in part or in
whole, so you can add its functions to an existing DHTML application if
you wish without rewriting your existing code. The functions can be used
with both static HTML markup and dynamically generated HTML markup.
Incidentally, much of this API was derived
from the source code in Mike Hall's excellent
Cross-Browser DHTML API, which no cross-browser DHTML developer should overlook.
That API dynamically generates the markup for all positioned HTML elements
and creates an array of pointers to each element's JavaScript object; this
array then provides an easy way to look up positioned HTML elements by
their name. Another excellent cross-browser DHTML API is contained in Dan
Steinman's free and thorough tutorial The
Dynamic Duo Cross-Browser DHTML. Both of these APIs provide additional
functionality not included in the Setting
CSSP Properties from JavaScript API so long as you use their methodologies
throughout your DHTML code.
CROSS-BROWSER EVENT HANDLING
Once again, Danny Goodman comes to the rescue,
explaining the differences between Navigator 4.0 and Internet Explorer 4.0
event handling in JavaScript
Apostle: Dueling Event Models -- A Cross-Platform Look; read that article
now if you're not already familiar with the differences. In a second article,
he explains Cross-Browser
Drag and Drop. To see a practical application which uses cross-browser
event handling, read the newly-updated TechNote discussing Version 3.0
of Netscape's Dynamic
HTML Presentation Template.
Take special care in your handling of resize
events. Resize events can cause dynamically positioned HTML elements to
lose their state. There are three ways to avoid this problem:
- You can make the window non-resizable.
- You can use Netscape's downloadable sample code which captures
the resize event and reloads the page.
- You could store the position of your elements in a session cookie, capture the resize event, and restore the elements'
positions from a session cookie when the window resizes.
FULL SCREEN MODE
Both browsers have the ability to create a
full-screen window as a canvas for the DHTML page. On Navigator 4.0, an unsigned
script can create a window the size of the entire screen and hide all of
its controls except for the title bar, which is required to be present
so the user has a way to close the window. If you wish to hide the title
bar as well, you must sign the script, and the script must ask the user
for and be granted the UniversalBrowserWrite privilege. (This prevents
hostile scripts from being able to take over the entire screen and deny
the user a way to escape.) To learn more about Netscape's capabilities-based
security model, read Danny Goodman's article
Applying Signed Scripts and visit Security Developer Central.
PROVIDING DOWNLOADABLE FONTS FOR BOTH BROWSERS
Navigator 4.0 and Internet Explorer 4.0 both provide the ability to create dynamically downloadable font resources which encode
the fonts your pages use so they can be viewed as intended on machines which do not have the fonts installed. However, the two browsers use different encoding formats for the font definitions, so if you want to provide downloadable
font resources on your site for both Navigator 4.0 and Internet Explorer 4, you will need to create one definition file in each format.Webmonkey has written an article called No More GIF Text! which demonstrates pages which have font resources for both browsers and summarizes the steps necessary to support both browsers.
TOOLS
Tools are emerging to bridge the gap between
Netscape DHTML and Microsoft DHTML. Following is a list of some of the
tools you can choose from:
Builder.com has published a competitive review of cross-browser DHTML development tools which you may find useful when choosing the tool that's best for you.
COMMENTS
Do you have comments, suggestions, or constructive
criticism about this article? Would you like to see another hint or tip
or workaround added? Do you have a cross-browser, cross-version code sample
you would like to submit? Please use these links to email us:
Want Netscape to Keep You Posted on Cross-Browser
DHTML?
From time to time, Netscape will release new
resources to assist in cross-browser DHTML development. If you would like
to be kept posted on new TechNotes, sample code, and information related
to cross-browser Dynamic HTML, join the xbrowser-list mailing list. If you ever change your mind, you can click here to remove yourself from the xbrowser-list mailing list.
Your email address will not be sold, bartered, or exchanged to any other organization.
- Related Readings:
-
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use