How to Create Resolution Independent Web Pages
Imagine a web page to automatically senses the size of your browser and renders the content so it fits perfectly. No horizontal scrolling. No blank columns. Everything just fits, as though it was made with just you in mind.
Websites generally come in one of two forms, fixed width or flexible width. Fixed width layouts give you as a designer, greater control over your design, but you must take into account the resolution of the average visitor to the site. Unfortunately this means visitors with a lower resolution will have to scroll horizontally and visitors with a higher resolution will have wasted screen space.
If you use a flexible width layout, it will display without horizontal scrolling and without wasted space, but the layout may break when the browser window is to narrow (not everything fits in the desired space and starts to overflow) or if the browser window is too wide, the content may become difficult to read, because the lines of text become too long.
A third option, inspired by an article by Pi, my JS Stopwatch and Apple's plans for Leopard to be resolution independent, is to dynamically resize the content to suit the size of your browser window. Javascript can be used to change the font size, image sizes and potentially the size of other content, so that the page is always the same width as the browser window.
Demonstration
In the demonstration of this technique, window.onload and window.resize call a fitToScreen function. The fitToScreen function determines the width of the browser window and the width of the content in order to determine a scaling factor.
Text and Layout Resizing
The scaling factor mentioned above is used to set the font-size CSS property of the body element as a percentage. The width of the columns, the margins and the padding are specified in font relative measurements (em and ex), so changing the font size on the body causes both the text and the layout to change.
The layout in the demonstration has been designed for the sidebar to have a width of 15em and for the main column to have with a width between 35em and 50em1. It's also possible directly set the width of the main column (rather than setting min-width and max-width ), but I chose to use min-width and max-width as that should keep both the fixed width and flexible width camps happy.
If your browser has a minimum font size set, then the page will only shrink as much as that minimum will allow, otherwise the page will reduce to however narrow you make the window (handy for getting an overview of how the page looks).
Image Resizing
Browsers already support image resizing, but if the original image is too small, the up-scaled version is going to look like rubbish and if it's too big then a lot of bandwidth will be wasted and your visitors will probably move on before it's finished loading. Add to this is the problem that there doesn't seam to be a way to resize background images on the client.
Resizing the image on the server allows you to have very large images (to avoid up-scaling), only delivers exactly what is required to the client (minimising bandwidth usage) and allows the scaling of backgrounds.
To scale the images on the server, a php script is used that uses two request parameters, image and width to determine which image to scale and what width to scale it to. The script then opens the image, scales it proportionally and outputs the result. The HTML for the images is changed from something like
<img alt="some description" src="someimage.jpg"/>
to something like
<img alt="some description" src="scaleimage.php?image=someimage.jpg&width=320"/>
and the CSS for the backgrounds is changed from something like
background-image: url( 'top.png' );
to something like
background-image: url( 'scaleimage.php?image=top.png&width=20' );
This results in someimage.jpg and top.png being delivered to the browser at 320px wide and 20px wide respectively regardless of their original widths.
The width of images specified in the HTML and CSS should be set to their desired width when the body font size is 100%. This will allow the images and backgrounds to display at the correct scale if the visitor has Javascript disabled.
In order to change the size of the images and the backgrounds with changes to the size of the page, we need to scale them by the same factor that is used to set the font size. We do this by updating the src attribute for img elements and the url specified for background images, with the new desired width.
Supported Browsers
The resolution independent web design demonstration has been tested in:
- IE 6 & 7
- Firefox 2.0
- Opera 9.1
- Safari 2.0.4
Further Work
As with most PoCs, further work is required in order to make this technique ready for production.
Images
In the demonstration, all images and elements with backgrounds have an id attribute specified, so they can be easily accessed via document.getElementById(). In a more general example, the Javascript code would need to traverse the entire document, adjusting the src and url as needed. jQuery seams well suited for this task.
The demonstration could be extended further by adding support for multiple copies of the same image at various resolutions. This is the technique used by finder icons in OS X, which are 128 x 128px, but allow you to provide "hints" at 16 x 16px and 32 x 32px.
SVGs
I haven't played around with SVGs, but they seam like an ideal companion for resolution independent layouts, if only they were natively supported in all the modern browsers. Another option could be to have SVGs on the server and use a service side script to convert them to the appropriately sized pngs for the clients.
Caching
Ideally scaleimage.php should cache copies of the images at their various sizes, so if the same image is requested at the same size multiple times, the image would only need to be resized once saving server CPU. Also, the images do not appear to be cached on the client. There are various php header directives that allow control of client side caching, but nothing I tried could get the images to cache on the client.
IFrames
Pages that contain iframe elements (google ads are contained within iframe elements) would need to resize the iframe and it's contents. I managed to set the fontsize of a document within an iframe, but nothing I tried allowed me to resize the iframe within IE 7 (Firefox as usual had no issues). Regardless of this, resizing iframe elements requires the contents of the iframe to support resolution independence, which currently isn't the case. This means most ads will break when resized. A temporary solution is to design you layout with a non-resolution independent section, like a banner area, which contains the ad. The main problem with this is the banner is usually the least clicked ad on a web page.
Resizing Other Media
I'm not familiar with flash, so I have no idea how easy or hard it is to resize. Given that most video content is delivered as flash these days, a technique for resizing flash is needed on any site that contains video and wants a resolution independent design. If resizing flash is too hard, one option would be to contain a thumbnail to the flash content in the page, which links to a non-resolution independent page that contains the flash content. Not exactly ideal.
Conclusion
Resolution independent web design provides a new option in the fixed vs flexible debate. Once the issues above are dealt with, designers using this technique needn't worry about the screen size of their visitors and can focus their attention on the real design aspects, like shiny buttons, bright colours and diagonal pin stripes.
Download
- except in IE 6, which uses a fixed width of 50em as it doesn't directly support the
min-widthandmax-widthCSS properties [back]
10 comments.










Hi,
Very interesting, but the download file is missing
Thanks. Fixed.
Hi,
here is my dirty solution for dynamic flash resizing (using JQuery):
/* on document resize */
var resizeTimer = null;
$(window).bind('resize', function() {
/* resize flash object */
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
$('#flash-object').width($('body').width());
$('#flash-object').height($('#flash-object').width() / 2.25 ); /* 2.25 = H/W ratio */
}, 100);
});
Nice one. Thanks for that.
There are several things you need to do. Browsers now will still actually make a request to the server for cached resources, but set some special headers to let the server determine if it needs to actually resend any data or not.
First, if you are using PHP sessions for some reason (I recommend against it in an image script), you have to set the cache limiter directive to ‘public’, see session_cache_limiter().
Second, you have to make sure that you are sending an ETag header. This is just some unique string that identifies the specific image (different for each size). You can do something as simple as sending the image file name followed by the modification stamp followed by the resolution. i.e., “image.png-45045098345-320×230″
Third, you must send a Last-Modified header, which must be formatted exactly per the HTTP spec. gmdate(’D, d M Y H:i:s T’, $timestamp) will do this for you. $timestamp is the modification date of the image file.
Fourth, you have to actually use the modern cache control feature. The client will send two HTTP headers: If-Modified-Since and If-None-Match. These are set to, respectively, the modification timestamp (in the above format) and the Etag the browser received when last it pulled the image. If these are both equal to the current calculated timestamp and Etag, then you must return the HTTP status code 304 Not Modified and the Etag header, but nothing else (no image data). Otherwise, you need to send the new Last-Modified header, the new Etag header, the Content-Type header, the Content-Length header, and then of course the image data itself.
Wow. Thanks Sean. I’ll give that a try as soon as I get a chance.
Thanks Sean. Your caching guide worked a treat. I’ll have an updated version of the demo available soon.
Thanks for your inspiring article tom. I’ve put up a scaling site. Check out http://www.geminidowns.com.au/
This is really amazing code! I have a 20″ monitor with 1600×1200 resolution, and I have to set the minimum font size in Firefox to 18 to make things readable. I turned it off, tested your page, and it looked great!
However, it seems pretty wrong to size things according to the window size. When I size my window smaller, the text gets unreadably small. Why not use the screen size instead? Is screen.width and screen.height not portable?
I have created a website http://www.sanviprojects.in. The webpage is right now resolution dependent and changes when the resolution changes. I used the technique that is mentioned here but could not solve the issues. Can you please be kind enough to help me solve the problem? Thanks in advance.