Web browsers differences

From Elvanör's Technical Wiki
Jump to: navigation, search

Internet Explorer

General

  • Usually if you get an "Expected identifier, string or number" error, this means you have an extra "," at the end of a class or JS object. The best way is to comment out the injected JS files until you find out which one has the problem.
  • Only use Prototype JS code or you'll run into troubles (mainly because all elements should be extended Prototype elements to ensure cross-browser behavior).
  • IE caches *a lot*. In particular Ajax requests can be cached! Be sure to put some caching directives on the server side, else IE simply won't hit your server again. It'll use the cached version.
  • IE has problems with "different encodings" on the same webpage. If the original document is encoded in ISO-8859-1 and then an Ajax call receives UTF-8 data that is added to the DOM, IE will produce weird characters. Firefox works fine with these cases.
  • UPDATE: This is actually only because IE ignores the Content-Type HTTP header in the case of dynamic scripts. You can make it work correctly by forcing the "charset" attribute of the script node to UTF-8 like this:
<script src="jspec.js" type="text/javascript" charset="utf-8"></script>

Developer tools

  • Debugging JavaScript on IE is a lot harder than on FF. For debugging JavaScript, the best way is to install Visual Studio Express Web 2008 and follow these instructions (IE has to be the default browser).
    • Choose New Web Site, then select an empty web site on the File System.
    • Click Run on this project, then change the URL and go to the actual webpage.
  • To get something similar to Firebug, install the Internet Explorer Developer toolbar.
  • To trace HTTP requests and their headers, install Fiddler (on Windows). This allows you to get functionality similar to the Net tab in Firebug.
  • IE 8 has a semi-decent, built-in developer toolbar. Press F12 to activate it.

CSS bugs

  • IE 7 has a bug regarding elements with z-index (absolutely positioned elements with relatively positioned parents). Basically if you have an relatively positioned element, it starts a new stacking context and thus its child will have their z-index based on this context... not the real context which is usually the body. Good explanation.
  • IE does not properly support CSS comments; multiple CSS comments on one line, with an actual property / value set, confuses the poor piece of crap.
  • IE does not like absolute positioning on anchor elements or images; but you can usually fix it by wrapping in a div or span. Apparently for IE it is better to give both top and left properties for absolutely positioned elements (eg, both coordinates).
  • text-align: center can also cause misbehavior, usually you can fix it by only applying this property to a subelement.
  • IE 7 does not support attribute selector when the attribute is "for" (on a label).
  • IE 7 has a strange behavior on an absolutely positioned element when top: is used (bottom is fine) and the relatively positioned ancestor has not a width of auto. Having a 100% width confuses IE. It is important with our technique for a generic skinning of a block for example (when the block did not have a fixed width this caused problems).
  • If you have new lines in anchor (<a>) elements, IE may mess your page (the behavior I got was that IE thought the page was very wide, so I got an horizontal scrollbar).
  • Relatively positioned elements on a div with overflow (when there is a scrollbar) don't behave properly. The solution is to add "position: relative;" to the container div (the one with overflow).
  • IE cannot apply display: inline-block to a div without a hack (setting display: inline for this div in a second rule, after the first rule specifying the display: inline-block). For inline elements this works fine.
  • Margins on inline-replaced elements (like images) behave poorly, as the text is not placed correctly vertically. You can add a vertical-align property to the container to try to fix this, but generally speaking, vertical margins for inline-replaced elements are dangerous.
  • A descendant of an absolute element whose height has been set via top: 0px; bottom: 0px; will not get the correct computed height if we set it via height: 100%. An interesting reference. A solution is to position absolutely the child.
  • The bottom margin of a div can have strange effects on a sibling div that would have a relative position and would contain absolute divs. See this page for an exemple. If you use padding instead of margin or if you insert a clearer div, you are safe.
  • In Internet Explorer and Opera, some images inside links (anchor elements) sometimes have an ugly underline. You must set text-decoration: none; manually on such elements (the <a> themselves). I don't know exactly what triggers this behavior; it seems to be somewhat linked to margins.

Floating Bugs

  • Vertical margins of an element next to a float may appear between the last float in the flow and a clear element. See this bug for reference. Solution is to either change the margin to padding, or apply a clearer div.
  • Horizontal margins on a relatively positioned element descendant of a float can produce problems.
  • IE seems to have a bug when multiple floated divs are present on a container, with their widths in percentage. If the percentage amounts to exactly one hundred (100%), then it will not render correctly. To fix this, you can just make the widths go only to 99% if possible.

Bugs in tables

  • IE 7 does not recognize max-width (and probably min-wdith too) in tables.
  • IE has a problem with the width of a cell when the content is larger than the width and the text cannot be broken (no whitespace). A workaround is to use a div with a fixed width inside the td. This will work.

Opacity

  • You can use opacity in a non standard way in IE via the filters:
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; // IE 8
filter: alpha(opacity=50); // IE 7 and below
  • This method has a bug: the text smoothing will be disabled. You need a background-color set or possibly a width set to make it work. The best way is to not use the opacity in elements that contain text.

JavaScript bugs

  • The "change" event does not work as expected on checkboxes (it fires only when the checkbox loses focus). A workaround is to use the "click" event.
  • Same thing for radio buttons.
  • When adding a CSS rule dynamically to a stylesheet, IE chokes if the rule selector part actually contains more than one selector. Eg, if the selector contains the "," syntax element. You must manually break the rule into two rules before.
  • Also note that when dealing with stylesheets dynamically, IE seems to be at least 20 times slower than Firefox.
  • IE cannot update the contents of an inline CSS stylesheet with Prototype update() (or innerHTML). The changes won't be displayed instantly on the page. You must use the CSS stylesheet APIs to do this.
  • The results of a regular expression evaluation in IE may be empty strings, whereas in Firefox it's undefined (null) objects.
  • IE forbids the use of appendChild(), update() - or innerHTML - on a style element. A workaround:
newElement = new Element("style", {"type": "text/css", "id": id});
newElement.styleSheet.cssText = data;
  • Another workaround, with more code (but potentially works better):
while (true)
{
	try
	{
		inlineStyleSheetElement.styleSheet.removeRule();
	}
	catch (e)
	{
		break;
	}
}

data.split("}").reverse().each(function(rule)
{
	if (-1 != rule.indexOf("{"))
	{
		rule = rule + "\n}";
		ruleSelectorPart = rule.substr(0, rule.indexOf("{"));
		ruleSelectors = ruleSelectorPart.split(",");

		
		ruleSelectors.each(function (ruleSelector)
		{
			inlineStyleSheetElement.styleSheet.addRule(ruleSelector, rule.substr(rule.indexOf("{")));
		});	
	}
});
  • IE does not fire the "load" event for script elements. The only way to know when IE has finished loading the script is to call a callback function at the end of the script file.
  • The "keypress" event does not work for detecting tab key presses. "keydown" works fine.
  • removeAttribute() does not work on IE, so use Prototype's writeAttribute(attr, false).

Different behavior than Firefox (not necessarily bugs)

  • IE 7 automatically adds margins to forms. You can override that behavior with CSS.
  • IE adheres to the W3C P3P standard. This means that cookies will be blocked depending on a P3P policy. This can especially happens with third party cookies (cookies sent by a different host). You have to definie a P3P policy to work around that. The simplest thing to do is to add a compact policy to your HTTP headers, for example:
P3P: CP="NOI NID CUR DEV OUR STP UNI"

Look at the official P3P specification for more information.

Links

IE 6

  • IE 6 goes into quirks mode (even worse behavior) if you put an XML prelude into your served XHTML document.
  • IE 6 can be made more IE 7 compliant with the help of a script. This script redownloads the CSS stylesheets via an XMLHttpRequest, so beware of crossdomain calls (if the stylesheet is not on the same domain, nothing will happen).

Opera

  • The "Exceptions have stack trace" option should really be activated to do any kind of debugging with Opera. It must be activated via opera:config#UserPrefs|ExceptionsHaveStacktrace, there is no way to set that in the Preferences dialog.
  • location.hash is bugged when the hash contains a question mark. Update: this seems to have been fixed.
  • myForm.readAttribute("action") behaves differently in Opera, as it adds the hostname before (which is bad!). The bug was apparently fixed in Opera 9.50 (see this bug reference).

CSS

  • When using an element with fixed position at the bottom of the page, you usually add an absolutely positioned element with a negative bottom value to provide scrolling. This technique does not seem to work very well in Opera.
  • Opera automatically adds margins to forms.

JavaScript

  • Opera has a default behavior when using a mousedown event on an image. You can prevent that from happening with event.stop() in Prototype as usual. However, if in the same function you move an image directly under the mouse (for example this could be the case with a slider...), another mousedown event launches, this time on the moved image! And then you get the annoying behavior. This can easily be fixed by stopping the second event. I consider this a bug as Firefox does not launch the second event. Once the original event is stopped, nothing further happens.
  • Opera does not fire the "load" event on an newly created image, which has already been downloaded (eg, whose source corresponds to an already fetched element). This is probably a bug that hopefully will be fixed.

WebKit

Safari

  • Safari has a development / debug mode, but it does not seem to work well under Windows.

Chromium / Chrome

  • You can disable cache entirely by going to the Dev Tools panel, then Network, then Disable cache (checkbox). Unfortunately there is no command-line way or programmatic way to accomplish this. The --disk-cache-dir=/dev/null only disables disk cache. It is not enough as Chromium uses RAM quite extensively.
  • A workaround is to send very strict HTTP headers from the server, that entirely disable caching. This works well.

Security

  • WebKit does not allow third party browsers by default, and strictly enforces this.

JavaScript

  • Safari does not allow the contents of a XHTML style element to be updated. A workaround is to remove the element, and add a new style element.
  • On Chrome, creating a script node then using scriptNode.innerHTML = code; can lead to strange errors when code is a very, very big string. Use the following code instead:
scriptNode.appendChild(document.createTextNode(code));

Firefox

CSS

  • You cannot correctly change the properties of a file upload form field with CSS. Firefox has a bug that prevents width from correctly working on the associated text field. All other browsers support this correctly though.
  • Firefox has a bug with display: table-cell and borders. See this bugzilla report and the demonstration page.

JavaScript

  • Firefox 3 has a bug that prevents the use of the stylesheet DOM APIs on an external stylesheet, eg a stylesheet hosted on an external host. The workaround is to use an inline stylesheet.
  • This also prevents Firefox from reading the rules contained in an external stylesheet. Note that one workaround is to create an element that you know will get a rule applied on the current page; you can then read its style.
  • When retrieving a URL value for a CSS property via getComputedStyle(), in Firefox the quotes around the URL are removed:
background-image: url("http://www.google.com/logo.png"); -> url(http://www.google.com/logo.png)

This is not the case in all other browsers where quotes are still present.

Firebug Lite

  • The current 1.2.1 version of Firebug Lite is broken (loads all the time when opened, even on Firefox). The best way to currently use Firebug Lite is to load it via a bookmarklet.