Monday, April 24, 2006

High DPI Web Sites

One area of Web design that is going to become more important in the coming years is high DPI. For those of us working on WebKit, this will also become an issue for WebKit applications and for Dashboard widgets.

What is DPI?

DPI stands for “dots per inch” and refers to the number of pixels of your display that can fit within an inch. For example a MacBook Pro has a 1440×900 resolution on a 15 inch screen. Screens exist for laptops, however, that have the same physical size (15 inches) but that cram many more pixels into the same amount of space. For example my Dell XPS laptop has a 1920×1200 resolution.

Why does this matter?

Consider a Web page that is designed for an 800×600 resolution. Let’s say we render this Web page such that the pixels specified in CSS (and in img tags and such on the page) map to one pixel on your screen.

On a screen with 1920×1200 resolution the Web site is going to be tiny, taking up <>

Now this may not be a huge problem yet, but as displays cram more and more pixels into the same amount of space, if a Web browser (or any other application for that matter) naively continues to say that one pixel according to the app’s concept of pixels is the same as one pixel on the screen, then eventually you have text and images so small that they’re impossible to view easily.

How do you solve this problem?

The natural way to solve this “high DPI” problem is to automatically magnify content so that it remains readable and easily viewable by the user. It’s not enough of course to simply pick a pleasing default, since the preferences of individuals may vary widely. An eagle-eyed developer may enjoy being able to have many open windows crammed into the same amount of space, but many of us would like our apps to remain more or less the same size and don’t want to have to squint to read text.

The full solution to this problem therefore is to allow your user interface to scale, with the scale factor being configurable by the user. This means that Web content has to be zoomable, with the entire page properly scaling based off the magnification chosen by the user.

What the heck is a CSS px anyway?

Most Web site authors have traditionally thought of a CSS pixel as a device pixel. However as we enter this new high DPI world where the entire UI may be magnified, a CSS pixel can end up being multiple pixels on screen.

For example if I set a zoom magnifcation of 2x, then 1 CSS pixel would actually be represented by a 2×2 square of device pixels.

This is why a pixel in CSS is referred to as a relative unit, because it is a unit whose value is relative to the viewing device (e.g., your screen).

CSS 2.1 describes how a the px unit should be rescaled as needed.

http://www.w3.org/TR/CSS21/syndata.html#length-units

What’s wrong with zooming?

Zooming an existing Web page so that it can be more easily viewed has a number of immediate benefits. Text remains readable. Images don’t become so tiny that they can’t be viewed.

Doing naive zooming, however, will result in a Web site that - when scaled - looks much worse. (Try looking at what happens to images in Internet Explorer for Windows when you change the OS DPI setting from 96 to 120 for example.) Several factors come into play here.

For example, with text you don’t want or need to “zoom” it. In other words, you aren’t going to take the actual pixels for each character and scale them like you’d scale an image. Instead you simply use a larger font size. This will allow text to have a higher level of detail on high DPI displays and ultimately look more and more like the text you might see in a printed book.

For images, you first and foremost need a good scaling algorithm. You’d like for the image to look about as good as it did on a lower DPI display when rendered at the same physical size. However, the problem with scaling of existing images is that all you’ve done is maintained the status quo, when instead you could be designing a Web site that looks *even better* on these higher DPI displays.

How can I make images look better?

Consider a common Web site example: the use of images to do UI elements like buttons with rounded corners and fancy backgrounds. Let’s say the Web designer uses a 50×50 pixel image for the button. The rounded corners and background may look reasonably nice on a lower DPI display and even continue to look nice when the image is scaled by 2x but rendered at the same physical size on a higher DPI display.

What if you could use a 200×200 image instead? Or, even better, what if you used an image format that hadn’t hard-coded all of its pixel information in the first place? The use of either a higher resolution image (with more detail) or of a scalable image format allows for the creation of images that would look *better* when rendered on the higher DPI display.

Enter SVG

Safari actually supports PDF as an image format (the hands of the clock Dashboard widget are an example of this). However other browsers do not support this format. The agreed-upon standard for scalable graphics on the Web is SVG.

Find out about SVG

SVG stands for Scalable Vector Graphics and is an XML language for describing two-dimensional images as vector graphics. Describing graphics in this fashion allows for the creation of images that will look better on high DPI displays when rendered at the same physical size.

Our goal with WebKit is to make SVG a first-class image format, so that it can be used anywhere you might use a PNG, a GIF or a JPG. In other words, all of the following should be possible:



div {
background-image: url(tiger.svg)
}

li {
list-style-image: url(bullet.svg)
}

Our current thinking regarding SVG images used this way is that they would be non-interactive (in other words you can’t hit test elements inside the SVG’s DOM). It’s debatable whether or not script execution should be allowed when SVG is used this way.

These are some issues we’d like to hammer out, since we view this use of SVG as being very different from SVG included explicitly in a compound XHTML document or included via the use of an