When you design for the web, you don’t know what software people will use to experience your site, and you don’t know what capabilities your users (and their software) have. Flexible layouts and resizable type can eliminate a lot of worst-case usability and design scenarios, but it’s still extremely difficult to create page layouts that don’t break even if the user increases the type size by more than a few settings.
Stick around and we’ll give you a way to detect your visitors’ initial font size setting—and a way to find out whenever your visitor increases or decreases the font size. Why would you want to know these things? Because with this knowledge in hand, you can create a set of stylesheets that adapt your pages to the users’ chosen font sizes, preventing overlapping elements and other usability and design disasters. (You can also do a lot of other interesting things, which we’ll discuss later.)
Our sample page before font resizing.
Our sample page with overlapping navigational elements after the font size is increased.
Flexible design approaches#section2
Some existing techniques—like Dan Cederholm’s “Bullet Proof CSS,” faux columns that simulate columns with background images, and oversized images and background-position that allow for growth of text—are a great help, but some designs just aren’t meant for large text. Furthermore, you won’t want to serve bite-sized content to visitors with large resolutions just to cater to visitors with smaller resolutions—if you can avoid it.
Designing into the unknown#section3
Before we get into the technique itself, let’s take a step back and examine the underlying problem.
We already know how to adapt to the size of the user’s window and screen resolution. Stuart Colville’s CSS Drop Column Layout shows content in four columns and drops the fourth below the third when there is not enough space on the screen. An older script by Cameron Adams allows for window-size dependent styling. If you use Cameron’s resolution script, your website can learn when the visitor’s window gets resized and react to it accordingly. Sadly, this is not the case when you resize the font.
How to detect font size changes#section4
- creates a hidden
spanelement with a space inside it,
- reads the height of that element and stores it,
- registers listener functions to call when the font size changes, and
- checks periodically if the height of the
spanelement changed—which means that the user has resized the font.
This is nothing new, and it has been used on some high-traffic web portals before. It becomes a lot more interesting, though, when you mix it with custom events. In essence, using a custom event means you get notified every time there is a change in font size.
Check the demo page to see the effect in action. (Resize the font in your browser to get the notifications.)
Using the text resize detector#section5
To implement this script, first embed it in the
head of your document. (Line wraps marked » —Ed.)
Next, define two properties:
idof the element you want to add the
- the name of the function that gets called when the text resize detector is initialized.
These are stored in two parameters called
Note: to determine the correct base font of the document, the element
id that you store in
TARGET_ELEMENT_ID should be fairly high
in the source order and not inherit font size from any other element. This also
means that the detector runs as soon as possible.
If you don’t care about the base font size, you can specify any element.
Lastly, define the function that you set in the
init() function is where you register listeners with
addEventListener. This ensures that your function—in this case
onFontResize()—is called when the font size has been changed.
It also returns the base font size, which is useful for Opera and IE7
A tangent: Opera and IE7#section6
These browsers take a different approach to resizing: instead of increasing the font size, they zoom the whole document, including form elements and images. As these browsers don’t resize the font, the event will never fire. However, the script allows you to initially read out the base font size and help you adjust your layout / widget according to that base size.
Back to work#section7
Once you’ve set everything up, you can define your listener function. (Line wraps marked » —Ed.)
When the event fires, this function retrieves two parameters: the name of the event—
textSizeChanged—and an array of arguments, the first of which is an object with the following properties:
- The initial value of the document when it was loaded.
- The difference between the last font size and the new font size.
- The new font size.
All font sizes are in pixels.
TextResizeDetector object itself has three methods:
- Registers your event handler and returns the base font size. If you pass an object as a second parameter, your handler function is executed in the scope of that object.
- Stops the detector.
- Starts the detector. This is only needed if the
stopDetector()method has been executed beforehand.
That’s grand, but what do you do with this information? Whatever you please. Possible options include
- Turning a horizontal menu bar into a vertical single list when the font is too large.
- Replacing a graphical button with a normal submit on large fonts
- Applying different style sheets to the document according to font size. You could also automatically switch to a zoom layout at a certain stage.
- Removing elements when a certain size is reached.
- Showing more elements when a certain size is reached (in case the user zooms out instead of in).
- Pulling in longer text passages via Ajax when the screen space allows for longer texts.
- Increase the width of a sidebar when the font size changes to keep a consistent line length.
- Center an element that is defined in em on the screen.
How else might this script be used? Tell us about it in the comments.
That is all there is to it. You can download
all the code and examples in this zip.
For more info about custom events, here are two good resources.