|
IntroductionSafari 3 brings massive performance and usability improvements to Mac OS X. At its core is the WebKit engine that powers Safari for both computer desktops and iPhone, as well as for iPod touch. WebKit is also a public framework used not only by many third-party applications, but also by Apple applications such as Mail, Help Viewer and iChat. Dashboard is another feature of Mac OS X built on top of WebKit. This web-based architecture enables you to write powerful widgets using the same standard technologies—HTML, CSS and JavaScript—that you use to create web pages. As the WebKit engine evolves, then, so does Dashboard. The WebKit engine behind Safari 3 contains a number of improvements to site compatibility and standards compliance. As these changes occur, it is important to make sure all of your content—including Dashboard widgets—is ready to take advantage of this new engine. This Technical Note demonstrates a number of nonstandard practices that may cause problems in WebKit as of Safari 3, and what you can do to avoid these problems. All proposed solutions continue to work with earlier WebKit clients. Be sure to review each of these cases. Many web and widget development problems are hard to track down, and often display symptoms completely unrelated to the actual problem. This Technical Note helps you quickly identify any potential issues with your content. Strict HTML and CSSA number of issues across browsers can be solved by declaring a strict doctype and running your HTML and CSS code through a validator. This is a great way to ensure compatibility and reduce time spent troubleshooting issues that may arise in one web engine or another. Below are a few examples of problems that can be avoided by using a doctype and validator prior to deploying your content. See Safari HTML Reference and Safari CSS Reference for more examples of practices and standards enforced by Safari and WebKit. Using DOCTYPE to Ensure Predictable Element SizeWeb engines fall back to an unpredictable compatibility mode (or modes) when faced with certain nonstandard conditions or code. The best way to prevent unexpected behavior from these “quirks modes” is to declare an explicit doctype such as HTML 4.01 strict. The example in Listing 1 is one of many cases where entering quirks mode can produce unexpected results. In this example, the generated textarea ends up with a computed style height different from the requested height in the CSS. Listing 1: HTML without a doctype. <html>
<head>
<title>Text Area test</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
textarea {
height:54px;
}
</style>
<script>
function load() {
var ta = document.getElementsByTagName("textarea")[0];
alert(document.defaultView.getComputedStyle(ta).height);
}
</script>
</head>
<body onload="load();">
<textarea>I've set the height to 54px.</textarea>
</body>
</html>
Figure 1: Conflicting requested and computed styles.
This discrepancy occurs because WebKit has entered quirks mode and is attempting to produce behavior that best matches legacy rendering behavior of many browsers. Quirks modes are not predictable across browsers and can easily be avoided by adhering to a known doctype. This problem is solved by adding a single line to the top of the markup, as shown in Listing 2. Listing 2: HTML 4.01 strict doctype. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd"> This simple change identifies your content to WebKit and allows it to operate according to the declared doctype. Figure 2 illustrates the single-line fix: the computed style now matches the height requested in the CSS. Figure 2: Matching requested and computed styles.
Hex Colors in CSSDeclaring a document type imposes requirements on your HTML and CSS. For example, when using the HTML 4.01 strict doctype all CSS hex color values must begin with a hash mark ( The CSS in Listing 3 will be ignored by WebKit, resulting in a default background color for the page. Listing 3: Improper hex color value in CSS. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hex Colors in CSS</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type='text/css'>
body {
background-color: FF0000;
}
</style>
</head>
<body>
This page has a red background.
</body>
</html>
Figure 3: Improper CSS colors are ignored.
Adding the hash to this property causes the requested color to be respected by Safari 3 and later. Listing 4: Proper hex color value in CSS.
body {
background-color: #FF0000;
}
Figure 4: Proper CSS colors are respected.
IMPORTANT:
Working with Elements in the DOMReferencing Elements by idCertain browser engines allow elements to be referenced using their unique ids as properties of the global Listing 5: A simple HTML form <form id="myForm">
<input id="myInput">
</form>
The DOM API standard states that any JavaScript code should fetch the IMPORTANT:
Retrieving Nonstandard Element AttributesSimilar to the above case, shortcut notation for custom attributes on elements in the DOM is not supported. To read or write a nonstandard attribute on an element, use the The following example demonstrates the difference between the standard DOM code and code written using shortcut notation. The span element in this example defines a custom attribute "name", whose value "MessageSpan" is then fetched and written using Javascript. Listing 6 fetches the attribute using regular object notation. Listing 6: Nonstandard access of custom attributes. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Referencing Custom Attributes</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type='text/css'>
span {
padding: 5px;
border: 1px solid black;
}
</style>
<script type='text/javascript'>
//Loads an image
function showSpanName() {
var messageSpan = document.getElementById("message");
messageSpan.innerHTML = "The name of this element is <b>" + messageSpan.name + "</b>";
}
</script>
</head>
<body onload='showSpanName();'>
<span id='message' name='MessageSpan'></span>
</body>
</html>
Use of the Referencing the Figure 5: Nonstandard access of custom attributes.
The Listing 7: Proper access of custom attributes.
function showSpanName() {
var messageSpan = document.getElementById("message");
messageSpan.innerHTML = "The name of this element is <b>" + messageSpan.getAttribute("name") + "</b>";
}
Figure 6: Proper access of custom attributes.
IMPORTANT:
Images and GraphicsScaling Images with HTML and CSSAnother common confusion on the web involves scaling of images. Scaling occurs when the requested dimensions do not match the actual dimensions of a given image. If such a discrepancy only occurs in a single dimension (e.g. width but not height), some browser engines will only scale that dimension and ignore the image's actual aspect ratio. This behavior does not match the CSS specification, which requires aspect ratio always be preserved when only a single dimension is explicitly set. WebKit matches the specification and respects the image's aspect ratio unless told otherwise. As an example, Listing 8 constructs a graphic element using left and right ends, and a stretched middle piece. The center image has a width of 1 pixel and height of 20 pixels. In this example, the center piece's width has been set to 50 pixels, resulting in an image scale. Note that this example controls element size in HTML, not CSS. However the same rules apply in either case. Listing 8: A three-piece graphic element. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Three-Piece Image</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<div id='pill'>
<img src='left.png' alt=''><img width='50' src='middle.png' alt=''><img src='right.png' alt=''>
</div>
</body>
</html>
Figure 7: Image scaled with maintained aspect ratio.
Figure 7 looks bad enough, but it's been trimmed: the center content actually runs 1000 pixels high. This is because only the width attribute was specified on the image and, matching the spec, WebKit preserved the aspect ratio when scaling the image. Explicitly setting the height of the 'center' Figure 8: Image scaled against aspect ratio.
CanvasThe canvas element was introduced as an HTML extension in Safari 2. It has since gone through a draft specification process with the WHATWG, allowing for consistent implementations by other engines such as Gecko. The WebKit engine behind Safari 3 enforces this specification, and all canvas code should be tested for compliance. The specification has four key characteristics that previously were not enforced:
These points are detailed with concrete examples in Working with the WebKit Nightly Builds. ConclusionThe examples in this Technical Note are just a few cases where coding to standards can pay off on Safari as well as other browsers and web-based environments such as Dashboard. If you're working in Safari, Dashboard, or WebKit, you can always test your content against nightly builds of Safari from http://nightly.webkit.org to make sure you've adopted compatible techniques that will benefit you and your users over the long term. Further ReadingDocument Revision History
Posted: 2007-09-25 | ||||||||||
|