Sunday, November 05, 2006

Box Model

The Box Model

The box model defines how browsers lay out their pages, using their height, width, padding, margin and border. The standards-compliant ("standards mode") way is to take the height and width, and add the padding and borders onto these values. So a box with a width and height of 100px and a padding of 50px would have an overall height and width of 300px. This is how it is defined in the W3C standards, and how all browsers do it apart from Internet Explorer when running in "quirks mode" (ie backwards compatible, non-standards). IE includes the padding and border within the width and height. This difference means that you have to provide CSS hacks so that elements are the same size in IE quirks and standards-browsers.

However, the situation has just been rectified, and also got more complicated. IE7 now adheres to the W3C standards box model. IE6 almost adheres to the W3C standards when it is in standards mode, but not in quirks mode. The mode that it uses to lay out a page is dependent on the DOCTYPE. Pre-IE6 browsers use the quirks layout mode for all DOCTYPEs.

Layout mode used in Internet Explorer 6 based on Doctype
DoctypeUrl in Doctype?Xml Declaration?Layout Mode
HTML 4.01 StrictNoNoStandards
HTML 4.01 TransitionalNoNoQuirks
HTML 4.01 StrictYesNoStandards
HTML 4.01 TransitionalYesNoStandards
XHTML 1.0 StrictYesNoStandards
XHTML 1.0 TransitionalYesNoStandards
XHTML 1.0 StrictYesYesQuirks
XHTML 1.0 TransitionalYesYesQuirks
See here for full list.

To get round the box-model inconsistencies, we use CSS hacks that take advantage of browser bugs or differences in CSS support to target different browsers. A common way to differenciate IE from standards-browsers is to use the !important declaration in your CSS. This tells all standards-browsers not to override this value - but IE doesn't understand !important, so you can override the value on the line below and it is picked up by IE only. In IE7 beta2, they had fixed the box model, but not the !important bug. This meant that the CSS hack compensated for a bug that no longer existed. Fortunately, in the first full release of IE7, this situation has been remedied, and !important is now recognised, and therefore the hacks still work as they recognise IE7 as a standards-compliant browser. Phew! I tested this in version 7.0.5730.11 and was extremely relieved. This just leaves IE6 in strict mode (ie non-quirks) as the problem - this will use standards based box model, but still has the !important bug.

References

Its a big month for browsers

Major Browser Upgrades

Its a big month for browsers, and we haven't seen anything like this before. The big two browsers vendors, Microsoft and Mozilla, have launched major new versions of their browsers virtually at the same time. Internet Explorer 7 and Firefox 2 are available now; but the really significant thing is that IE7 will be pushed to desktops via a Windows Update. Now that broadband is commonplace, the uptake of these browsers will be very rapid indeed. Previously, it used to take 6 months to a year for a new browser to take hold, now we can expect a significant uptake almost overnight.

Another significant point is that W3C standards will be better supported in IE7, and we can expect the number of bugs and inconsistencies between browsers to reduce as a consequence.

The Box Model

IE has always had a different (non-standard) box model to other browsers, but this has been put right for any document with an XHTML DOCTYPE. However, this may cause issues with IE6, because this uses the old box model for XHTML. Will the CSS hacks work?

Font Smoothing and Accessibility

One problem with producing fully accessible websites was that in Windows XP, ClearType font smoothing is turned off by default, and IE used the same setting as the OS. This meant that any large font sizes meant ragged, low quality-looking text on the majority of browsers. In IE7, ClearType font smoothing is turned on in the browser by default, regardless of the OS setting. This setting can be found in Tools>Internet Options>Advanced>Multimedia>Always use ClearType for HTML. This means that producing an accessible site will no longer mean that the typography will appear low quality, and therefore should enable a more accessible internet.

ClearType/Filter issue

Unfortunately, there is a bug regarding the use of DXTransforms filters with ClearTypeTo avoid this bug, IE7 disables ClearType for anything with a DXTransforms filter. This is rubbish, and makes pages that use filters look inconsistent. Maybe we should ditch DXTransforms filters now? However, it doesn't look like IE7 supports the CSS 'opacity' property, so how are we meant to get transparency in IE?

Printing

IE has always had problems with its printing, and rendering of print previews. IE7 promises better.

RSS

The new generation of browsers also provide for better out-of-the-box support for RSS (Really Simple Syndication), as this becomes an integral part of the web.

PNG image support

Currently, most websites use JPEG and GIF images. JPEG support 16 million colours, but no transparency. GIF images support 256 colours, and on/off transparency. Unfortunately, this means that you can't anti-alias into a transparent background using a GIF, which is a serious drawback. PNG images offer the best of both worlds, supporting 16 million colours and variable transparency, allowing each colour 256 levels of transparency. This opens up a whole new world of web design, especially when combined with CSS layers.

Firefox already supports PNG, but up to and including IE6, Internet Explorer didn't support the variable transparency feature of the PNG format. This has severely limited its use on the web, meaning that JPEGs and GIFs are still the dominant image formats on web pages. With IE7 now supporting PNG variable transparency, this probably marks the start of the shift from JPEG and GIF to PNG for images on the web.

Zoom

IE7 has added a Zoom feature to help with accessibility. Instead of just increasing the size of the font, and probably messing up the page layout, it takes a leaf out of Opera's approach and scales the whole page. This is a better experience for the user with poor eyesight, and also easier for the developer to cater for.

Tabs

Tabbed browsing has been available in Firefox for ages, but now IE7 has adopted a similar approach, and this will mean that users will get used to browsing in a consistent way, with multiple tabs within one browser window, rather than having many instances of IE open on the desktop. Better use of the favicon in the address bar, the tab heading and in the Favorites/Bookmarks makes it easier for a website to communicate its branding.

Current Statistics

Browser Usage Statistics 2006
Browser Usage Oct 06
IE7 3.1%
IE6 54.5%
IE5 3.2%
Firefox 1.x 28.8%
Firefox 2.x 0%
When the figures are available for November and December, I predict that we'll see a significant shift to IE7 and Firefox 2 - but what will be the extent of this? It would be fantastic for front-end developers if the majority quickly migrate to IE7 and Firefox 2, as this will mean that all the hacks and workarounds to support old versions of browsers can be forgotten, and sites that are XHTML and CSS 2.0 standards-complient will look good and consistent for a majority of users. This should help the adoption of best practices and remove a burden from web development.

Friday, November 03, 2006

Filters in Internet Explorer

Fade Filter

One of the few IE-only features that I like are filters, and especially the fade transition filter. It just adds a bit more quality to the page, and degrades gracefully in other browsers.

Define the filter in your stylesheet:

div#filterElement { filter: progid:DXImageTransform.Microsoft.Fade(duration=2) height: 20px; width: 100px; background-color: blue; }

One gotcha is that you need to define a width and height for the filters to work. Then add the javascript to perform the transition:

function showDiv(divId) { var myDiv = document.getElementById(divId); myDiv.style.visibility='hidden'; myDiv.style.display='block'; if( myDiv.filters) { myDiv.filters[0].Apply(); } myDiv.style.visibility='visible'; if( myDiv.filters) { myDiv.filters[0].Play(); } }

Applying a filter effectively takes a snapshot of the element at that point in time. You then change its state behind the scenes, then Play() the transition, so in this case it blends between the state at Apply() and the state at Play(). Don't hide the element (display: none;) because doesn't display the element at all, and the transition is hidden from view. Using visibility: hidden keeps the element in place, but hides its contents.

Hiding the element is a bit more tricky, because the transition doesn't block the javascript, and so you hide the element immendiately after you start playing the transition, and the transition is hidden too. You therefore have to use the onfilterchange event on your element (IE only).

function hideDiv(myDiv) { if( myDiv.filters) { myDiv.filters[0].Apply(); } myDiv.style.visibility='hidden'; if( myDiv.filters) { myDiv.filters[0].Play(); } } function removeDiv(myDiv) { if( myDiv.style.visibility == 'hidden' ) { myDiv.style.display='none'; } }

Then, put the event on the element to remove the element from the page:

<div onclick="showDiv('filterElement')">Click to show</div> <div id="filterElement" onclick="hideDiv(this)" onfilterchange="removeDiv(this)">Click to hide</div>