<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>QuirksBlog</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/" />
<modified>2008-04-30T15:49:30Z</modified>
<tagline></tagline>
<id>tag:www.quirksmode.org,2008:/blog//1</id>
<generator url="http://www.movabletype.org/" version="3.14">Movable Type</generator>
<copyright>Copyright (c) 2008, ppk</copyright>

<entry>
<title>Event compatibility tables</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/04/event_compatibi.html" />
<modified>2008-04-30T15:49:30Z</modified>
<issued>2008-04-30T15:48:13Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1597</id>
<created>2008-04-30T15:48:13Z</created>
<summary type="text/plain"><p>Today I unveil my most ambitious update to the DOM compatibility tables: the Events compatibility tables. All in all I think I spent two weeks&amp;#8217; of work on them; testing all common events not only in common situations, but also in unusual ones. A quick test of basic browser support for W3C and Microsoft events completed this series of tests.</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Content</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Somewhere near the end of February I started working on my site again as a sort of therapy to get over my burn-out. I focused on the compatibility tables, which were in desperate need of an update; I hadn't published any major new versions since 2005. Besides, new browser versions are proliferating all over the place and people need to know what these browsers can and can&#8217;t do.</p>

<p>Today I can finally unveil my most ambitious update: the <a href="/dom/events/index.html">Events compatibility tables</a>. All in all I think I spent two weeks&#8217; of work on them; testing all common events not only in common situations, but also in unusual ones. A quick test of basic browser support for W3C and Microsoft events completed this series of tests.</p>
]]>
<![CDATA[<p>Creating the <a href="/dom/events/tests/">test pages</a> was a major chore that swallowed more and more time as they progressed; I&#8217;m still not sure if what I did was smart or too smart. Anyway, they&#8217;re done now and will remain mostly unchanged for at least a year.</p>

<p>Unfortunately the testing of the load and unload events didn&#8217;t really fit the test format I devised; therefore information on these events is still lacking. (They generally work fine, though.)</p>

<p>Now only the <a href="/dom/w3c_events.html">Events properties table</a> remains to be done, but first I&#8217;m going to take a well-deserved break from event testing.</p>
]]>
</content>
</entry>
<entry>
<title>Delegating the focus and blur events</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html" />
<modified>2008-04-14T19:07:50Z</modified>
<issued>2008-04-14T14:16:26Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1585</id>
<created>2008-04-14T14:16:26Z</created>
<summary type="text/plain"><p><![CDATA[Nowadays many JavaScripters are aware of the advantages of event delegation. Chris Heilmann and Dan Webb, among others, have discussed its advantages, and I've been using it as much as possible for about two years now.

Event delegation is especially useful in effects like dropdown menus, where lots of events on links may take place that can easily be handled at the root level (an &lt;ol&gt; or &lt;ul&gt; in this case).

There used to be one problem, though: although event delegation works fine for the mouse events, it does not work for the focus and blur events we need to make dropdown menus keyboard-accessible.

In the course of my ongoing event research, however, I found a way to delegate the focus and blur events, too. Maybe one of those
frightfully
clever
JavaScript
library
authors
will use this technique to shave off a few milliseconds of computing time

For all I know they're already aware of this technique; but it was new to me so I publish it anyway.
]]></p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Coding techniques</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Nowadays many JavaScripters are aware of the advantages of event delegation. <a href="http://icant.co.uk/sandbox/eventdelegation/" class="external">Chris Heilmann</a> and <a href="http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery" class="external">Dan Webb</a>, among others, have discussed its advantages, and I've been using it as much as possible for about two years now.</p>

<p>Event delegation is especially useful in effects like dropdown menus, where lots of events on links may take place that can easily be handled at the root level (an <code>&lt;ol&gt;</code> or <code>&lt;ul&gt;</code> in this case).</p>

<p>There used to be one problem, though: although event delegation works fine for the mouse events, it does not work for the focus and blur events we need to make dropdown menus keyboard-accessible.</p>

<p>In the course of my ongoing event research, however, I found a way to delegate the focus and blur events, too. Maybe one of those
<a href="http://alex.dojotoolkit.org/" class="external">frightfully</a>
<a href="http://ejohn.org/" class="external">clever</a>
<a href="http://script.aculo.us/thomas/" class="external">JavaScript</a>
<a href="http://developer.yahoo.com/yui/" class="external">library</a>
<a href="http://conio.net/" class="external">authors</a>
will use this technique to shave off a few milliseconds of computing time</p>

<p>For all I know they're already aware of this technique; but it was new to me so I publish it anyway.</p>
]]>
<![CDATA[<p><a href="/focusblurexample.html">Example</a>.</p>

<h3>What is event delegation?</h3>

<p>For those unaware of it, let's briefly discuss event delegation. As context I'll use a dropdown menu.</p>

<p>When a user uses a mouse to steer through a dropdown menu, you want to capture all mouseover and mouseout events in order to see whether the latest user action should open or close a menu. (You also have to carefully distinguish between useful and useless events because Firefox, Safari and Opera still don't support the <a href="http://msdn2.microsoft.com/en-us/library/ms536945(VS.85).aspx" class="external">mouseenter</a> and <a href="http://msdn2.microsoft.com/en-us/library/ms536946(VS.85).aspx" class="external">mouseleave</a> events, but that's another story.)</p>

<p>The mouseover and mouseout events <a href="/js/events_order.html">bubble up</a>; that is, when a mouseover event on a link fires, the event "climbs" the DOM tree to see if any mouseover event handlers are defined on the ancestor nodes of the link. It first checks the link itself, then goes on to the containing <code>&lt;li&gt;</code>, followed by the <code>&lt;ol&gt;</code>, and all the way up to document or window level.</p>

<p>That means that it's perfectly possible to define your generic onmouseover and onmouseout event handlers on the <code>&lt;ol&gt;</code> that forms the root element of the dropdown menu. When these events take place lower in the tree, event bubbling makes sure they eventually end up at the root element and can be handled there.</p>

<pre>
&lt;ol id="dropdown"&gt;
	&lt;li&gt;&lt;a href="#"&gt;List item 1&lt;/a&gt;
		&lt;ol&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.1&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.2&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.3&lt;/a&gt;&lt;/li&gt;
		&lt;/ol&gt;
	&lt;/li&gt;
	[etc.]
&lt;/ol&gt;

$('dropdown').onmouseover = handleMouseOver;
$('dropdown').onmouseout = handleMouseOut;
</pre>

<p>The great advantage of this trick is that you don't need to set two event handlers on every link, which may  save some browser memory.</p>

<h3>The focus problem</h3>

<p>This works fine. However, as soon as you want to make your dropdown keyboard-accessible, too, you run into a problem.</p>

<p>In theory, making a dropdown keyboard-accessible is easy: you just define event handlers for the focus and blur events, too. The problem is that these events do not bubble up. A focus or blur event on a link fires only on the link itself, and not on any ancestor element of the link.</p>

<p>This is an ancient rule. A few events, most motably focus, blur, and change, do not bubble up the document tree. The exact reasons for this have been lost in the mist of history, but part of the cause is that these events just don't make sense on some elements. The user cannot focus on or change a random paragraph in any way, and therefore these events are just not available on these HTML elements. In addition, they do not bubble up.</p>

<p>Take the following situation:</p>

<pre>
&lt;p id="testParagraph"&gt;
	Some text.
	&lt;input id="testInput" /&gt;
&lt;/p&gt;

$('testParagraph').onfocus = handleEventPar;
$('testInput').onfocus = handleEventInput;
</pre>

<p>When the user focuses on the input field, the <code>handleEventInput</code> function is executed. However, the event does not bubble up, so <code>handleEventPar</code> is not executed. In addition, it's not possible to focus on the paragraph (except when it has a <code>tabindex</code> attribute), so <code>handleEventPar</code> is never executed.</p>

<h3>Event capturing</h3>

<p>Except when you use event capturing.</p>

<p>Event capturing is the reverse of event bubbling. When an event bubbles up it starts at the event target and then moves up the DOM tree. When an event is captured, it starts at the top of the DOM tree (usually the window or document object) and then moves <em>down</em> to the event target.</p>

<p>One of the most curious conclusions of my event research is that when you define event handlers in the capturing phase the browser executes any and all event handlers set on ancestors of the event target <em>whether the given event makes sense on these elements or not</em>.</p>

<p>So let's take the same example as above, but now with <code>addEventListener</code> in the capturing phase. (You define it on the capturing phase by setting the last argument to <code>true</code>.)</p>

<pre>
&lt;p id="testParagraph"&gt;
	Some text.
	&lt;input id="testInput" /&gt;
&lt;/p&gt;

<del>$('testParagraph').onfocus = handleEventPar;
$('testInput').onfocus = handleEventInput;</del>
$('testParagraph').addEventListener('focus',handleEventPar,<strong>true</strong>);
$('testInput').addEventListener('focus',handleEventInput,<strong>true</strong>);
</pre>

<p>Now if the user focuses on the input, the event starts at the window or document level and then moves down to the input. On the way it encounters the onfocus event handler on the paragraph and executes it, even though the event does not make sense on a paragraph.</p>

<p>As a result, <code>handleEventPar</code> is executed, and then <code>handleEventInput</code>.</p>

<h4>IE</h4>

<p>Unfortunately IE does not support event capturing. However, it supports the <a href="http://msdn2.microsoft.com/en-us/library/ms536935(VS.85).aspx" class="external">focusin</a> and <a href="http://msdn2.microsoft.com/en-us/library/ms536936(VS.85).aspx" class="external">focusout</a> events that, contrary to focus and blur, do bubble up. If we use these events to get IE on board, we're ready to sail.</p>

<h4>Delegating the focus and blur events</h4>

<div class="floater">
<p>Opera (9.5b) incorrectly fires all focus and blur events twice.</p>
</div>

<p>Therefore the conclusion must be that onfocus and onblur event handlers may be delegated just as onmouseover and onmouseout are by <em>registering them in the capturing phase</em>. In order to properly delegate all events for a keyboard-accessible dropdown menu you do:</p>

<pre>
&lt;ol id="dropdown"&gt;
	&lt;li&gt;&lt;a href="#"&gt;List item 1&lt;/a&gt;
		&lt;ol&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.1&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.2&lt;/a&gt;&lt;/li&gt;
			&lt;li&gt;&lt;a href="#"&gt;List item 1.3&lt;/a&gt;&lt;/li&gt;
		&lt;/ol&gt;
	&lt;/li&gt;
	[etc.]
&lt;/ol&gt;

$('dropdown').onmouseover = handleMouseOver;
$('dropdown').onmouseout = handleMouseOut;
$('dropdown').onfocusin = handleMouseOver;
$('dropdown').onfocusout = handleMouseOut;
$('dropdown').addEventListener('focus',handleMouseOver,<strong>true</strong>);
$('dropdown').addEventListener('blur',handleMouseOut,<strong>true</strong>);
</pre>

<p>Now you've succesfully delegated the focus and blur events.</p>

<p><a href="/focusblurexample.html">Example</a>.</p>

<h3>Further questions</h3>

<p>The fact that the capturing phase of the event works different from the bubbling phase raises a few questions, which I might answer at a later date:</p>

<ol>
	<li>Shouldn't event bubbling and event capturing work exactly the same way? That is, shouldn't both phases either execute all event handlers they find or use the old "only on sensible elements" rule?</li>
	<li>Isn't it time to allow all events to bubble up?</li>
</ol>

<p>(Note: In the case of focus and blur, it might make sense for the events not to bubble up. After all, if a user focuses on a link or form field, you don't want any generic window.onfocus to fire, because on the window that event has a totally different function: it fires when the user focuses on the entire browser window.)</p>
]]>
</content>
</entry>
<entry>
<title>Slides PFcongrez 2008</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/04/slides_pfcongre.html" />
<modified>2008-04-13T13:57:20Z</modified>
<issued>2008-04-13T13:55:24Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1581</id>
<created>2008-04-13T13:55:24Z</created>
<summary type="text/plain"><p>Yesterday I gave my first ever conference presentation in Dutch at the Pfcongrez, the annual conference of the PHP Freakz, the largest Dutch organisation for PHP programmers.

The presentation went well; I talked about the principles of unobtrusive JavaScript and it turned out that this concept was new to many attendees. I hope to have made a difference somewhere.
</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Conferences</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Yesterday I gave my first ever conference presentation in Dutch at the <a href="http://pfcongrez.nl" class="external">Pfcongrez</a>, the annual conference of the <a href="http://phpfreakz.nl" class="external">PHP Freakz</a>, the largest Dutch organisation for PHP programmers.</p>

<p>The presentation went well; I talked about the principles of unobtrusive JavaScript and it turned out that this concept was new to many attendees. I hope to have made a difference somewhere.</p>
]]>
<![CDATA[<p><a href="/presentations/pfcongrez2008/phpfreakz.pdf">Here are the slides</a> (in Dutch). I also promised to put the useful links online; here they are:</p>

<ul>
	<li>Chris Heilmann:<br />
	<a href="http://onlinetools.org/articles/unobtrusivejavascript/" class="external">Unobtrusive Javascript</a><br />
	<a href="http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/" class="external">The seven rules of Unobtrusive JavaScript</a><br /></li>
	<li>Jeremy Keith:<br />
	<a href="http://www.alistapart.com/articles/behavioralseparation" class="external">Behavioral Separation</a></li>
	<li lang="nl">Het moet ook van de overheid:<br />
	<a href="http://www.webrichtlijnen.nl/handleiding/ontwikkeling/productie/client-side-script-dom/optionele-karakter/" class="external">Het optionele karakter van client-side scripts</a></li>
</ul>

<p>If you want to hear me talk about unobtrusive JavaScript in English, come to <a href="http://aneventapart.com/events/2008/boston/" class="external">An Event Apart Boston</a> (June 23rd-24th), where I'll present an updated version.</p>
]]>
</content>
</entry>
<entry>
<title>Something odd happened on the way to mousemove</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/04/something_odd_h.html" />
<modified>2008-04-08T09:42:04Z</modified>
<issued>2008-04-02T13:58:01Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1576</id>
<created>2008-04-02T13:58:01Z</created>
<summary type="text/plain"><p>Currently I&apos;m working on a big revision of the Events Compatibility Tables. And no the new table is not yet online because I&apos;m not ready yet.

Testing event support is really awesomely complicated. I&apos;ve been working steadily for two weeks now, and I still find new bugs and oddities daily, and twice on Sundays.

In any case, I discovered something remarkable when I studied the mousemove event. It sheds light on the way browser vendors keep track of each other&apos;s implementations nowadays, and on things that can go wrong.

</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>IE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Currently I'm working on a big revision of the <a href="/js/events_compinfo.html">Events Compatibility Tables</a>. And no the new table is not yet online because I'm not ready yet.</p>

<p>Testing event support is really awesomely complicated. I've been working steadily for two weeks now, and I still find new bugs and oddities daily, and twice on Sundays.</p>

<p>In any case, I discovered something remarkable when I studied the mousemove event. It sheds light on the way browser vendors keep track of each other's implementations nowadays, and on things that can go wrong.</p>

<p><strong>Update</strong>: The bug described in this entry is an OS problem, and not a browser bug.</p>
]]>
<![CDATA[<p><del>When doing my <a href="/js/events/mousemove.html">new mousemove test</a> I found a bug in IE5-7 that I was previously unaware of. When the user moves the mouse over the element, the mousemove event fires many times, as it should. However, when the user <em>stops</em> moving the mouse, IE5-7 continues firing the event every once in a while. This stops only when the mouse leaves the target element entirely.</del></p>

<p><del>This is obviously a bug: when the mouse does not move the mousemove event should not fire.</del></p>

<p><del>The IE team reacted correctly: the bug has been solved in IE8b1. When the mouse does not move any more the mousemove event stops firing, as it should.</del></p>

<p><del>However, this same bug was recently <strong>introduced</strong> in Safari (Windows) and Opera!</del></p>

<p><del>Safari 3.0 and Opera 9.26 support mousemove correctly, but Safari 3.1 and Opera 9.5b have copied the IE bug.</del></p>

<p><del>What seems to have happened is that the IE team took a close look at other browsers' mousemove implementation, discovered that the IE5-7 implementation was buggy, and decided to correct the bug.</del></p>

<p><del><em>Simultaneously</em>, however, the Safari and Opera teams were also studying other browsers' mousemove implementation, discovered the IE5-7 bug and decided to implement it in their latest versions.</del></p>

<p>Their decision is understandable: it's a fact of life that web developers code with IE as baseline, and therefore other browsers must sometimes copy IE bugs.</p>

<p>Nonetheless, the position switch that IE and Safari/Opera have performed just now is unusual, and things like this shouldn't happen too often.</p>

<p>There are lessons to be drawn here. Although all four browser vendors are paying close attention to each other's implementation, it might make sense to discuss potential improvements before actually implementing them. That won't be easy, certainly not for the IE and Safari teams who're part of large companies that have a history of secrecy, but still it's something to be considered.</p>

<p>Besides, it makes me wonder about the wisdom of copying IE's bugs. After all, now that IE is moving quite close to the standards, the IE team may suddenly decide to solve a bug that has been left untouched for many versions.</p>

<p>Although I'm very happy about the increased communication between the various browser vendors, it seems they should cooperate even closer in order to prevent such odd reversals of position. (And the Safari team should send representatives to <a href="http://2008.sxsw.com/interactive/programming/panels_schedule/?action=show&id=IAP060348" class="external">interesting browser vendor panels</a>, but that's another story.)</p>
]]>
</content>
</entry>
<entry>
<title>CSS OM, take 2</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/03/css_om_take_2.html" />
<modified>2008-03-21T18:58:13Z</modified>
<issued>2008-03-21T16:46:41Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1575</id>
<created>2008-03-21T16:46:41Z</created>
<summary type="text/plain"><p>Just now I re-tested the CSS Object Model, both to accomodate IE8b1, FF3b4 and Safari 3.1, and because some of my earlier conclusions were wrong.
</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Content</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Just now I re-tested the <a href="/dom/w3c_cssom.html">CSS Object Model</a>, both to accomodate IE8b1, FF3b4 and Safari 3.1, and because some of my earlier conclusions were wrong.</p>
]]>
<![CDATA[<h3>getBoundingClientRect()</h3>

<p>In my <a href="/blog/archives/2008/02/the_cssom_view.html">previous post</a> I dismissed <code>getClientRects()</code> and <code>getBoundingClientRect()</code> as incomprehensible, but now I understand I should test them with multi-line inline elements. When the methods are used on such elements, they (should) return one rectangle per line.</p>

<p>I rewrote the <a href="/dom/tests/rectangles.html">test page</a> to show absolute elements at the rectangle coordinates, and now it's clear how <code>getClientRects()</code> is supposed to work, and that IE5.5-7 have significant bugs with this method: they report far too many rectangles. (IE8b1 does the right thing, BTW.)</p>

<p>Thanks to <a href="http://ejohn.org/blog/getboundingclientrect-is-awesome/" class="external">John Resig</a> for taking the lead in dissecting a few browser oddities with these methods.</p>

<h3>offset</h3>

<p>I also retested the <a href="/dom/tests/offset.html">offset-related properties</a>, and Travis Leithead of the IE team revealed the cause of Opera's weird negative values for <code>offsetX/Y</code>: Opera's reference point is the top/left of the content block (excluding padding and border), while Safari and Konqueror use the top/left of the element's border.</p>

<p><del>I summarily judged Opera's implementation Incorrect, because the Safari way seems to be the most logical one. I'm open to counter-arguments, though.</del></p>

<p><strong>Update</strong>: The spec says that the correct reference point is the top/left of the <strong>padding-box</strong>, which makes sense. Page changed to reflect that.</p>

<p><strong>Update 2</strong>: Went through the <a href="/dom/w3c_css.html">CSS Table</a>, too. No surprises, except for one minor IE8b1 regression. However, I now count IE's support of its own <code>rules[]</code> array Incorrect for reasons mentioned in the table. This is an old bug.</p>
]]>
</content>
</entry>
<entry>
<title>IE8b1 tests and more CSS tests</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/03/ie8b1_tests_and.html" />
<modified>2008-03-18T16:56:17Z</modified>
<issued>2008-03-18T13:14:32Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1571</id>
<created>2008-03-18T13:14:32Z</created>
<summary type="text/plain"><p>In the past few days I&apos;ve worked a bit on my compatibility tables. IE8b1 information has been added to the W3C DOM Core and HTML tables.

Furthermore I&apos;ve taken the opportunity to present the CSS compatibility table better. I split the page into two tables, CSS 2.1 and CSS 3, and I added a few CSS tests. The table below shows the new tests and their browser compatibility.

Update: Added Safari 3.1 Windows information to the main CSS table only.

Finally, a question. Who knows of CSS 3 declarations that don&apos;t yet figure in the CSS table but are supported by at least one browser? (Nightlies don&apos;t count, but betas do.) Please leave a comment with declaration name and supporting browser. It&apos;ll help me get my testing priorities straight.
</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Content</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>In the past few days I've worked a bit on my compatibility tables. IE8b1 information has been added to the <a href="/dom/w3c_core.html">W3C DOM Core</a> and <a href="/dom/w3c_html.html">HTML</a> tables.</p>

<p>Furthermore I've taken the opportunity to present the <a href="/css/contents.html">CSS compatibility table</a> better. I split the page into two tables, CSS 2.1 and CSS 3, and I added a few CSS tests. The table below shows the new tests and their browser compatibility.</p>

<p>Update: Added <a href="http://www.apple.com/safari/" class="external">Safari 3.1 Windows</a> information to the main CSS table only.</p>

<p>Finally, a question. Who knows of CSS 3 declarations that don't yet figure in the <a href="/css/contents.html">CSS table</a> but are supported by at least one browser? (Nightlies don't count, but betas do.) Please leave a comment with declaration name and supporting browser. It'll help me get my testing priorities straight.</p>
]]>
<![CDATA[<h3>New CSS pages</h3>

<table class="compatibility" cellspacing="5" style="margin-right: 0">
	<col />
	<col span="4" class="IE" />
	<col span="2" class="FF" />
	<col span="3" class="Rest" />
	<tr class="compheader">
		<th>Declaration</th>
		<th>IE 5.5</th>
		<th>IE 6</th>
		<th>IE 7</th>
		<th>IE8b1</th>
		<th>FF 2</th>
		<th>FF 3b4</th>
		<th>Safari 3.0 Win</th>
		<th>Opera 9.5b</th>
		<th>Konqueror 3.5.7</th>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/counter.html">counters</a></div>
		</td>
		<td class="comp no" colspan="3">No</td>
		<td class="comp yes">Yes</td>
		<td class="comp yes" colspan="2">Yes</td>
		<td class="comp yes">Yes</td>
		<td class="comp yes">Yes</td>
		<td class="comp yes">Yes</td>
	</tr>
	<tr>
		<td colspan="9"><p>To assign counters to headings or other elements.</p></td>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/enabled.html">:enabled, :disabled and :checked</a></div>
			For enabled, disabled, or checked form fields.
		</td>
		<td class="comp no" colspan="4">No</td>
		<td class="comp yes" colspan="2">Yes</td>
		<td class="comp yes">Yes</td>
		<td class="comp yes">Yes</td>
		<td class="comp yes">Yes</td>
	</tr>
	<tr>
		<td colspan="9"></td>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/nthchild.html">:nth-child() and :nth-of-type()</a></div>
			Select elements according to a formula
		</td>
		<td class="comp no" colspan="4">No</td>
		<td class="comp no" colspan="2">No</td>
		<td class="comp no">No</td>
		<td class="comp incomplete">Static</td>
		<td class="comp yes">Yes</td>
	</tr>
	<tr>
		<td colspan="9">
		<p>Opera doesn't update the styles correctly when elements are added dynamically.</p>
		</p>
		</td>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/mediaqueries.html">Media queries</a></div>
			Allows you to define blocks of styles that only take effect on certain monitor sizes.
		</td>
		<td class="comp no" colspan="4">No</td>
		<td class="comp no" colspan="2">No</td>
		<td class="comp incomplete">Static</td>
		<td class="comp yes">Yes</td>
		<td class="comp no">No</td>
	</tr>
	<tr>
		<td colspan="9">
		<p>Safari assigns the styles statically on page-load and doesn't update them.</p>
		</p>
		</td>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/beforeafter_content.html">content</a></div> for <code>:before/:after</code>
		</td>
		<td class="comp no" colspan="3">No</td>
		<td class="comp incomplete">Incom<wbr />plete</td>
		<td class="comp almost" colspan="2">Almost</td>
		<td class="comp incomplete">Incom<wbr />plete</td>
		<td class="comp almost">Almost</td>
		<td class="comp almost">Almost</td>
	</tr>
	<tr>
		<td colspan="9">&nbsp;</td>
	</tr>
	<tr>
		<td class="declaration" rowspan="2">
			<div class="name"><a href="/css/resize.html">resize</a></div>
			Allow the user to resize an element.
		</td>
			<td class="comp no" colspan="4">No</td>
		<td class="comp no" colspan="2">No</td>
		<td class="comp yes">Yes</td>
		<td class="comp no">No</td>
		<td class="comp no">No</td>
	</tr>
	<tr>
		<td colspan="9">&nbsp;</td>
	</tr>
	<tr class="compheader">
		<th>Declaration</th>
		<th>IE 5.5</th>
		<th>IE 6</th>
		<th>IE 7</th>
		<th>IE8b1</th>
		<th>FF 2</th>
		<th>FF 3b4</th>
		<th>Safari 3.0 Win</th>
		<th>Opera 9.5b</th>
		<th>Konqueror 3.5.7</th>
	</tr>

</table>
]]>
</content>
</entry>
<entry>
<title>IE8 beta 1 - first tests</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/03/ie8_beta_1_firs.html" />
<modified>2008-03-08T01:04:28Z</modified>
<issued>2008-03-08T00:58:07Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1561</id>
<created>2008-03-08T00:58:07Z</created>
<summary type="text/plain"><p>As everybody and his dog know by now, Microsoft has made IE8 beta 1 available. First impression: decent progress, but a lot of work remains to be done. And, in all fairness, this is merely a first beta, and its main purpose is to show where Microsoft is headed, and not to get every little thing right on the first try.

There&apos;s a lot to be said about its CSS and JavaScript support, and I&apos;m going to say it all. My readers, as well as the IE team, expect that.
</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>IE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>As everybody and his dog know by now, Microsoft has made <a href="http://www.microsoft.com/windows/products/winfamily/ie/ie8/default.mspx" class="external">IE8 beta 1</a> available. First impression: decent progress, but a lot of work remains to be done. And, in all fairness, this is merely a first beta, and its main purpose is to show where Microsoft is headed, and not to get every little thing right on the first try.</p>

<p>There's a lot to be said about its CSS and JavaScript support, and I'm going to say it all. My readers, as well as the IE team, expect that.</p>
]]>
<![CDATA[<h3>Regressions</h3>

<p>I'm going to start with a (doubtlessly incomplete) list of regressions: stuff that works in IE7 but not in IE8:</p>

<ol>
	<li><code>&lt;ol&gt;</code> numbering may be wildly and weirdly off; see the <a href="/dom/w3c_core.html">Core Table index</a>, for instance.</li>
	<li><code>scrollTop</code> and <code>scrollHeight</code> are off (<a href="/dom/tests/elementdimensions.html">test page</a>). Still have to determine how much off and if there's any rule.</li>
	<li><a href="/css/firstline.html">:first-line and :first-letter</a> don't work.</li>
	<li>The <code>attributes[]</code> array doesn't seem to have a <code>length</code>.</li>
	<li>The <a href="/dom/tests/tablesAccess.html#cells[]">cells[]</code> and rows[] nodeLists</a> don't work.</li>
	<li><code>letter-spacing</code> doesn't work in <a href="/css/selector_attribute.html">this page</a>. (The test is about the <code>tag[customAttribute]</code> selector, which works fine.)</li>
	<li><a href="/css/opacity.html">Opacity</a> doesn't seem to be supported (unless there's some odd syntax; I tried <code>-ms-opacity</code>, but that doesn't work, either).</li>
	<li>A really minor one: Some CSS selectors, such as <a href="/css/selector_adjacent.html">the + selector</a>, should also work when the page content is changed by JavaScript. In IE8 they do, but only after you remove the focus from the link that changed the page content.</li>
</ol>

<h4>Wrapper script problem</h4>

<p>Yesterday I went through my tests cases and found the problems listed above. However, in at least one case the problem was caused not by IE8, but by my <a href="/dom/tests/testscripts.js">DOM test page wrapper script</a> (although that problem, in turn, may be caused by IE8, since the wrapper script works fine in all other browsers, including IE5.5, 6 and 7).</p>

<p>When going through the <a href="/dom/w3c_core.html">Core table</a>, the first thing I noticed is that <code>insertBefore()</code> didn't work. I couldn't believe that the IE team would overlook a serious bug in such an important method and created a simple test case that was independent of my wrapper script. Result: <code>insertBefore()</code> works fine.</p>

<p>One more thing to take care of. Maybe I've been too smart in creating that wrapper script, although it works fine in all other browsers from 2006 onward.</p>

<p>I retested all of the problems listed above separately, and they're independent of my wrapper script.</p>

<h3>New CSS</h3>

<p>The IE team wants IE8 to fully support CSS 2.1 . Right now, that means that the following bits of CSS have been added (and I only tested those declarations I have tests for, so this list is definitely incomplete):</p>

<ol>
	<li><a href="/css/beforeafter.html">:before and :after</a> are supported, but you can't specify images, only text.</li>
	<li><a href="/css/focus.html">:focus</a> is supported.</li>
	<li><a href="/css/display.html#inlineblock">display: inline-block</a> is fully supported (used to be only on natural inline elements).</li>
	<li><a href="/css/display.html#table">display: table</a> and friends are supported.</li>
	<li><a href="/css/lists.html">list-style</a> support now complete, including the <code>upper-greek</code> value that no other browser supports.</li>
	<li><a href="/css/outline.html">outline</a> supported.</li>
	<li><code>border-collapse</code>, <code>border-spacing</code> and <code>caption-side</code> supported (<a href="/css/tables.html">test page</a>).</li>
	<li><a href="/css/whitespace.html">white-space</a> fully supported (used to be only two values).</li>
	<li><a href="/css/box.html">box-sizing</a> is supported, but it's <code>-ms-box-sizing</code>.</li>
</ol>


<h3>New JavaScript</h3>

<p><a href="http://ejohn.org/blog/javascript-in-internet-explorer-8/" class="external">John Resig</a> and <a href="http://erik.eae.net/archives/2008/03/06/11.09.51/" class="external">Erik Arvidsson</a> have already discussed IE8's JavaScript updates in detail, so I won't bother to repeat their lists.</p>

<p>And no, the W3C event model is not supported, and yes, I told the IE team what you think of that omission.</p>
]]>
</content>
</entry>
<entry>
<title>Austin planning</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/03/austin_planning.html" />
<modified>2008-03-07T01:22:18Z</modified>
<issued>2008-03-07T01:21:30Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1560</id>
<created>2008-03-07T01:21:30Z</created>
<summary type="text/plain"><p>As I think I said before, I&apos;ll arrive in Austin only on Saturday afternoon. I&apos;ve been very lazy this year and have made absolutely zero plans. However, I&apos;d like to kick off my personal SxSW experience by having a relaxed beer in The Ginger Man from about 5 to at least 7 pm. I&apos;m already supposed to meet some people there, but by this entry I&apos;d like to extend the invitation to anyone who&apos;s interested (or who wants beer).

Hope to see you there.
</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Conferences</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>As I think I said before, I'll arrive in Austin only on Saturday afternoon. I've been very lazy this year and have made absolutely zero plans. However, I'd like to kick off my personal SxSW experience by having a relaxed beer in <a href="http://austin.gingermanpub.com/" class="external">The Ginger Man</a> from about 5 to at least 7 pm. I'm already supposed to meet some people there, but by this entry I'd like to extend the invitation to anyone who's interested (or who wants beer).</p>

<p>Hope to see you there.</p>
]]>

</content>
</entry>
<entry>
<title>IE team changes its mind on IE8 default behaviour</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/03/ie_team_changes.html" />
<modified>2008-03-03T23:16:37Z</modified>
<issued>2008-03-03T22:58:40Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1554</id>
<created>2008-03-03T22:58:40Z</created>
<summary type="text/plain"><p>Just now the IE team announced that it&apos;s reversing its policy on the default behaviour of IE8,  which shows that it has been paying close attention to the discussion of its versioning proposal. I admit that I hadn&apos;t expected this reversal, but I welcome it.

</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>IE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>Just now the IE team <a href="http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx" class="external">announced</a> that it's reversing its policy on the default behaviour of IE8,  which shows that it has been paying close attention to the discussion of its versioning proposal. I admit that I hadn't expected this reversal, but I welcome it.</p>

]]>
<![CDATA[<p>Back in January, when A List Apart <a href="http://alistapart.com/articles/beyonddoctype" class="external">announced the versioning switch</a>, it was also announced that, left to itself, IE8 would use IE7 behaviour by default. Web developers could overrule this default and switch to IE8 behaviour by inserting the new <code>&lt;meta&gt;</code> versioning switch.</p>

<p>Today's decision reverses that behaviour: without a versioning switch IE8 will behave as IE8, although it will still be possible to switch it to IE7 behaviour, if desired.</p>

<p>Frankly, I hadn't seen this coming. I supported the previous system for two reasons:</p>

<ol>
	<li>I didn't (and don't) think that adding a <code>&lt;meta&gt;</code> switch or similar mechanism is such a hardship.</li>
	<li>It seemed that Microsoft really needed the default-to-IE7 rule in order to allow the Intranets of its corporate clients to continue working undisturbed.</li>
</ol>

<p>As of right now, the second reason has ceased to exist &#8212 and that's the bit that I didn't see coming.</p>

<p>Microsoft has decided to put the interests of web standards above the interests of the Intranets of its corporate clients.</p>

<p>I advise you to read the previous paragraph again. Even two years ago I had never expected to be able to write such a statement.</p>

<p>True, the versioning switch will allow anyone to adapt quickly: just set the switch to turn back the clock, and your website is saved.</p>

<p>Nonetheless, the IE team has done exactly what many standards-aware web developers wanted: it has put the onus on non-standardistas. If you want IE7 behaviour, fine, but you have to take action. If you just want standards and progressive enhancement, do nothing.</p>

<p>Isn't that something? The IE team is listening.</p>
]]>
</content>
</entry>
<entry>
<title>The CSSOM View Module</title>
<link rel="alternate" type="text/html" href="http://www.quirksmode.org/blog/archives/2008/02/the_cssom_view.html" />
<modified>2008-04-27T21:46:40Z</modified>
<issued>2008-02-29T13:07:39Z</issued>
<id>tag:www.quirksmode.org,2008:/blog//1.1551</id>
<created>2008-02-29T13:07:39Z</created>
<summary type="text/plain"><p>A week ago W3C published the first working draft of the W3C CSSOM View specification (written by Anne van Kesteren), and I must say I&apos;m very happy with it. Since I was testing stuff anyway I created a new compatibility table for most of the methods and properties specified in this document, and browser compatibility is already excellent.

That&apos;s no coincidence. This specification contains definitions for many properties (and a few methods) that browsers have already been supporting for ages (such as offsetWidth), and W3C has paid scrupulous attention to the current implementation. No more theorizing into the blue &amp;#8212; just check what browsers do and describe it in the specification. Excellent idea.

This blog entry talks about the crucial elementFromPoint method, and gives a few suggestions for improving the specification.</p></summary>
<author>
<name>ppk</name>
<url>http://www.quirksmode.org/</url>
<email>ppk@xs4all.nl</email>
</author>
<dc:subject>Standards/W3C</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.quirksmode.org/blog/">
<![CDATA[<p>A week ago W3C published the first working draft of the <a href="http://www.w3.org/TR/cssom-view/" class="external">W3C CSSOM View specification</a> (written by <a href="http://annevankesteren.nl" class="external">Anne van Kesteren</a>), and I must say I'm very happy with it. Since I was testing stuff anyway I created a new <a href="/dom/w3c_cssom.html">compatibility table</a> for most of the methods and properties specified in this document, and browser compatibility is already excellent.</p>

<p>That's no coincidence. This specification contains definitions for many properties (and a few methods) that browsers have already been supporting for ages (such as <code>offsetWidth</code>), and W3C has paid scrupulous attention to the current implementation. No more theorizing into the blue &#8212; just check what browsers do and describe it in the specification. Excellent idea.</p>

]]>
<![CDATA[<p>Almost all of these properties were originally invented by Microsoft and were copied by the other browser vendors &#8212; not only because IE's market share forced them to, but also because these properties were just good ideas.</p>

<h3>elementFromPoint</h3>

<p>One method deserves special attention: <code>elementFromPoint()</code>. This method expects two coordinates and then reports which HTML element is located at these coordinates. This is a godsend for drag-and-drop scripts. If the user drops an element, get the mouse coordinates and use this method to find out which HTML element is located at these coordinates.</p>

<p>One catch: you first have to temporarily hide the dragged element, because otherwise <code>elementFromPoint()</code> would always report the dragged element &#8212; after all it itself is the topmost element under the mouse.</p>

<p>I'm going to add this functionality to my <a href="/js/dragdrop.html">Drag and Drop</a> script, but for the moment this seems to be the idea:</p>

<pre>
releaseElement: function(e) { // called onmouseup
	var evt = e || window.event;
	dragDrop.draggedObject.style.display = 'none';
	var receiver
		= document.elementFromPoint(evt.clientX,evt.clientY);
	dragDrop.draggedObject.style.display = '';
</pre>

<p>Now <code>receiver</code> contains the element the user dropped the dragged object on.</p>

<p>Unfortunately the browsers do not entirely agree which mouse coordinates this method needs. IE and FF3 need <code>clientX/Y</code> (relative to the viewport), while Opera and Safari need <code>pageX/Y</code>
(relative to the document). I expect Opera and Safari to change their implementation, though; market share considerations leave them no other choice. And the brand-new working draft in fact specifies <code>clientX/Y</code>.</p>

<p>Firefox 2 does not support this method; Firefox 3 does.</p>

<h3>Critique of the specification</h3>

<p>Despite this <a href="http://www.w3.org/TR/cssom-view/" class="external">specification</a> being an excellent piece of work, I have several light points of critique. None of them is show-stopping, but the specification needs just a little bit more work to move from excellent to outstanding.</p>

<h4>WindowView</h4>

<p>I have doubts about the <code>WindowView</code> interface, which contains ancient properties such as <code>innerWidth</code>.</p>

<p>The problem is that <code>innerWidth/Height</code> and <code>pageXOffset/pageYOffset</code> are essentially doubles: they report the same information as <code>document.documentElement.clientWidth/Height</code> and <code>document.documentElement.scrollTop/Left</code>: the inner width of the viewport (browser window) and the scrolling offset of the document.</p>

<p>Since we already have that information available, why repeat it? The only reason would be that there might be situations where the <code>documentElement</code> does not span the entire viewport, but as far as I know these situations don't exist nowadays, and frankly I wonder if they'll ever exist.</p>

<p>I created a <a href="/dom/tests/documentElement.html">quick test</a> that gives the root <code>&lt;html&gt;</code> element a wide margin and a border. Clicking outside the border still reports the <code>&lt;html&gt;</code> element as target, and <code>document.documentElement.clientWidth</code> and <code>window.innerWidth</code> report the same number of pixels in all browsers.</p>

<p>So even though the root element may <em>appear</em> to cover only part of the viewport, JavaScript still acts as if it covers the entire viewport. That makes sense: there is no block-level element that contains the root element (or the root element wouldn't be the root element).</p>

<p>The other properties of the window view, <code>outerWidth/Height</code> and <code>screenX/Y</code>, are mostly useless. They've been around since Netscape 3, and in the ten years I've been writing scripts I've never needed to use either of them.</p>

<p>For al these reasons I'm wondering if the WindowView shouldn't be scrapped outright. It just serves no purpose.</p>

<h4>pixelDepth</h4>

<p>From the Browser Wars on, we've had two proprties that give the color depth of the screen: <code>colorDepth</code> and <code>pixelDepth</code>. The only difference between the two is that IE doesn't support <code>pixelDepth</code>. As far as I'm concerned we do not need two properties that contain exactly the same information, so <code>pixelDepth</code> should be removed from the specification.</p>

<h4>The getClientRects() and getBoundingClientRect() methods</h4>

<p>I don't understand these methods; or rather, the TextRectangle objects they return. They contain information</p>

<blockquote>
<p>about the position of the border box edges of an element relative to the viewport</p>
</blockquote>

<p>First of all we don't need this information; <a href="/js/findpos.html">finding the position</a> of an element is already possible.</p>

<p>I admit that there's no single property that holds this information; then why not create it? Something like <code>element.viewportOffsetX/Y</code> could be useful, and making this a property instead of a method would be more in line with the rest of the specification. (Should W3C go this way, it should also create an <code>element.documentOffsetX/Y</code> property pair.)</p>

<p>On the other hand, that would mean introducing a new property, and part of the point of this specification seems to be that it describes only properties that have already been implemented.</p>

<p>Finally, it seems that one element can contain several boxes, but I have not been able to find out why or how. In <a href="/dom/tests/rectangles.html">my tests</a> only IE sometimes reports more than one box, anyway.</p>

<p>I feel this part of the specification is not yet ready. At the very least, the relation of TextRectangle boxes to actual elements should be defined in the case there's more than one TextRectangle box, because I don't understand what to expect (and I suspect browser vendors don't, either, because Firefox and Opera never report more than one box, anyway).</p>

<p>Furthermore, I think that the inclusion of these methods should be critically reviewed, since I'm not sure they are useful enough to implement, especially not if their actual meaning is vague.</p>

<h4>x and y</h4>

<p>The specification also contains all mouse pointer property pairs; an area of JavaScript that featured truly horrible browser incompatibilities even at the time I wrote <a href="/book/">the book</a>. Fortunately, browsers have sanitised their act, and again the specification pays scrupulous attention to the actual implementation of these property pairs.</p>

<p>The single problem is the <code>x/y</code> property pair. The specification states they must return <code>pageX/Y</code>, but currently they return <code>clientX/Y</code> in all browsers, save Firefox, which doesn't implement <code>x/y</code> at all.</p>

<p>Again, why do we need a second property pair to hold information that's already available? Besides, in this single instance the specification departs from current browser behaviour.</p>

<p>My advice is to remove <code>x/y</code> completely.</p>

<h3>Conclusion</h3>

<p>Despite these minor points, the current working draft is an excellent piece of work that, I hope, will quickly grow to a fully-fledged recommendation. Browser vendors have to do very little in order to comply with this specification, and we badly needed these definitions.</p>
]]>
</content>
</entry>

</feed>