LET THE USER SET THE FONT SIZE

Let the user pinch-zoom their font size in your web page! Here’s why. And then how.

TL;DR : Use EMs for sizing, only use font-size at the leaf-node and then chuck in a couple of lines of JS.

Pinch zoom on mobile-web. Why do mobile web browsers do this?

It zooms but it cuts off all the text! I don’t pinch-zoom text so that I can madly scroll it side to side to read it, I pinch-zoom it because the text is too small and I want it to be bigger.

lets start with an all-too-realistic hypothetical:

I DESIGNED A WEBSITE ON MY MACBOOK PRO 15" AND IT LOOKS SH*T ON MY MUM’S LAPTOP? HOW CAN I MAKE HER BUY A NEW LAPTOP?

Have you ever been talking to your mum or dad, decided to show them something on your phone and as you bring it up to what you consider to be a reasonable distance from their face they launch their head backwards in a desperate attempt to get the phone into some older-person-focus-range that makes literally no sense? I have observed it many a time and I still don’t know why they do it. My parents are both glasses-wearers and they both do it, glasses or not.

If it were simply that they were short sighted then surely making the font on their phone really big would solve it? But no they seem to want to get to exactly a whole arms length away. I would ask them but I dread the answer will be that they’re both legally blind and shouldn’t be driving cars.

Similarly, they don’t ask me why font size is really hard to customise on computers because they dread the answer. Well at least they dread how long I’d go on about it for if they did ask. Ahem.

WHY DO COMPUTERS SUCK SO BADLY AT THIS?

In the past it was a race to the bottom for how absolutely terrible computers were at letting the user set a font size. Microsoft Windows would claim to let you but then flop around burning, screaming and exploding if you actually changed it to anything other than the default. Apple Macintosh didn’t let you because they’d paid someone in a skivvy an awful lot of money to decide what you should like and if you didn’t like it then it was your eyes that were incorrect and your only recourse was to try to become a better person. They ended up with the “accessibility magnifying glass tool” thing! They might as well have gone to the local center for people with vision impairments and started kicking people in the nuts.
Anyway I’m not talking about people with serious vision impairments. I have excellent vision and just like larger fonts because I’m a generally contrary person.

WHY DID THE ADVENT OF MOBILE BROWSERS HERALD A GLORIOUS NEW AGE OF STILL SUCKING AT THIS? JUST AS BADLY AS BEFORE?

Well when mobile browsers first came out they were stuck trying to make desktop websites at least sort of work on mobile devices because there were no mobile websites. So they had pinch-zoom for zooming into parts of the website, then zoom out again and then zoom in to the next bit. Which should really make any normal person want to fire their mobile device into the sun. Alternatively you could take a chance with double-tap zoom and hope you get lucky with your text-column and browser and website combo. Or more likely get most of the text too small and also the right hand side cut off by a couple of characters and then it’s back to firing it into the sun.

HOW BIG SHOULD THE FONT BE?

Well I’ve pondered this question and really you need to answer this question — how far away from the user’s face is the device and how much of their view do you want each character to occupy? You would have to be a nutter to try to code that. Like this guy: http://thenextweb.com/dd/2013/02/11/incredible-this-experiment-in-responsive-typography-uses-face-detection-to-adjust-font-size/

So instead I propose we just give the user a really easy way to adjust their font sizes, something easy, like a pinch-zoom gesture that only affects font size.

HOW CAN WE IMPLEMENT THAT IN THE WEB?

In the land of websites it seems like we had a golden opportunity to not suck as badly as these clowns but we dodged it just to get our work done quick. It is absolutely possible to build a website or web app that lets the user choose their own font size and then behave reasonably. It’s just a bit harder than using fixed font sizes and you also have to start with the concept or resize built in. If you’re already neck deep in a steaming pile of code and you’re only thinking about this now then it’s going to be an awful lot of re-work.

BEFORE WE START, THE UX DESIGNER WANTS IT TO BE EXACTLY XXXX PIXELS WIDE!

Well it’s time to put on your kilt and your blue facepaint and tell them that the hill tribes will no longer put up with their demands. In fact you don’t even need to do that, just build it so that it looks the way they want it at the default font size and everything else will just responsive-size itself into the right shape. ish. Trust me. Read on.

NOW YOU HAVE TO KNOW SOME REALLY BASIC CSS, SORRY.

To allow the user to decide their own font size, for starters, you couldn’t just say things like “my heading is 24px” anymore. You have to define every font size as relative to some base font size so that when the user changes their base font size everything scales nicely. You could do this laboriously with code or sass extensions or what-have-you neato trickery but my whole angle on this thing is that it’s been possible the _WHOLE_TIME_ and we just neglected to ever do it. So I’m going to use the magic of the EM unit. Also I just love low-fi. It’s the best.

EM units are a bit of a slippery fish though. The definition of an EM is “the width of an ‘m’ character in the font size that I’m currently in”. Which means that if you make a web element 10em wide then you change the font-size of it’s parent it gets bigger too. Even scarier, if you had a bunch of nested elements with font sizes set on them in EM units then each one is a multiplier of it’s parent’s font-size. That’s a bit scary. Most starter web devs have fallen into this sort of quicksand:

<div style=”font-size: 1em”> This part is at 1em or usually around 16px
 <div style=”font-size: 2em”> Then this part is at 2em
 <div style=”font-size: 2em”>but this part is now at 4 times the base font size! Yikes 64px high fonts! Trap for young players!

So EM units have a bad habit of changing size based on where they are in the document. CSS then introduced the REM unit (Root EM) which is all the goodness of EMs but without the relative-to-parent-font-size nonsense. Sounds great? NO! I actually *really want* the old fashioned EM behaviour. I want the user to set their desired font size and for all fonts and sizes in my app to change based on that. But I have to avoid the crazy multiplier example above. 
The way to do this is to be careful not to scatter font-size throughout the structure of my HTML, It means I can only use it to size the text bits. To make this a bit simpler I’m going to say that all text has to be in a P tag (even headings and little things like that) and the only place I can ever use the font-size directive is on the P tags.

To codify this into a set of rules:

1. All snippets of text must be wrapped in a P tag. (or some other standard inline tag that you set aside for the purpose)
2. P tags must only contain text and nothing else. If you want an image in between two words then you must split your sentence into two P tags and put the image between them. Etc.
3. The only font-size unit type you are allowed to use in CSS is EM. No px, no REM, nothing. Just EM.
4. Sizes of other elements on screen must not be in REM or PX sizes. Sometimes you may use %, sometimes you may use EM, but never REM or PX because they take control away from the user.

WHAT’S THE POINT OF ALL THIS?

AHA! I was hoping you’d wonder that! The point is, now that we’ve painstakingly set up our whole app or site to use text and sizes based on the root EM size, if the user changes their system or browser font size then our site just happily adapts! Or even better, if I add a gesture library in javascript I can allow the user to resize the fonts throughout the entire site with a pinch gesture and all the other stuff stays nicely in place.

BUT HOW DO I GET MY STUPID RESPONSIVE SITE BREAKPOINTS TO WORK?

Now it’s pretty common for people to use pixel sizes in their responsive breakpoints. They say things like “I want to go into tablet-mode if the site is more than 1200 pixels wide” but that doesn’t make loads of sense does it? Older laptops might be 1140px wide and get a really wide phone-like experience and modern tablets get a desktop site. It’s just not practical to use pixels and deep down we all know it, we’re just pretending we don’t because we gotta keep them cards moving across the wall.

Well the answer is obviously to use EM sizes for breakpoints too. Come on now. And if you can’t do it with media queries then you can do it with a few lines of JS that measure the width of an em and set a class name on a root element. (see the examples)

DOESN’T EVERYTHING USE “CSS PIXELS” SO I DON’T HAVE TO WORRY ANYMORE?

CSS pixels were invented because us web developers never properly implemented user controlled sizing. If sites had relative sizes everywhere then the modern retina display web browsers would be free to actually admit how many pixels they’ve got, but because you and I never created sites properly they had to lie to your css and I say the buck stops here.