Adapting a type scale based for users that zoom… a discussion and experiment
A few weeks ago I observed some people use a website with a very high zoom level and I haven’t been able to stop thinking about one specific thing.
Caveat: I am not suggesting this is something you do, or even something I do. I’m writing this to share an insight and try and understand if there’s something in it worth pursuing.
The default position
Websites generally speaking have some degree of responsive or fluid typography. You’ll likely see a change in type scale based on screen size, usually with a greater curve on large screens where there is more space available.
Just for the sake of it, say your type scale goes between 0.8rem
to 3rem
on small screens and 0.8rem
to4.2rem
on large screens.
When someone zooms into a website it’s expected that the fonts will get bigger and the layout will reflow. As you zoom in, your browser will start to reference styles in different breakpoints, meaning if your browser width is 1400px wide and you zoom 400% you’ll see the styles (and therefore the font scale) as if it was mobile.
What I observed
People tend to increase their zoom level based on their ability to read body copy. Most websites usually set this between 16px (1rem) and 18px (1.1rem).
When you use zoom, all fonts are scaled by the same amount to retain the same typographic hierarchy. The issue with this is that someone who may need to zoom a lot to read 16px type is presented with extremely large headings. In some cases, so large they may only be able to read them one character at a time.
In effect, the choices we’ve made around type hierarchy and emphasis have no meaning at this kind of zoom level. In fact, size-led typographic hierarchy has actually reduced user comprehension. Rather than being able to read entire words and put together sentence, users at this level of zoom are forced to put letters together into words and words into sentences, making content harder to consume.
What if?
I thought to myself, what if we could change type scale not only based on viewport size, but also zoom level.
Small viewport sizing may use an expected type scale such as 0.8rem
to 3rem
.
What if we could switch to an extremely shallow scale such as 0.8rem
to 1.75rem
at high zoom levels? This could potentially allow someone to be able to read headings as entire words. Dare I say, at it’s extreme type hierarchy doesn’t matter at all if you do not have the context of surrounding text.
Prior art — iOS Dynamic type
Dynamic type in iOS apps have something that works a bit like this. When a user increases their font size on an OS level, the designated styles such as “body” and “subhead” increase in size to different ratios. This stops presenting massive headings to people that just wanted to increase the body copy size.
Proof of concept
I should start this section by stating I am not a frontend developer — I’m a designer with enough knowledge to get by. I made this proof of concept to see what it would feel like and ideally do some research with real people.
After a lot of Google / Stack Overflow failures I came to the conclusion that was no way to achieve this in CSS — I genuinely hope I’m wrong. I was hoping there might be a separate @media
query for zoom level but I couldn’t find anything. 99.9% of conversations are just about the relationship with zoom level and min / max widths. Not what I wanted. I do not want this scale to be used on small screens, only when zoomed.
For this I went pretty basic. I created a type scale as some CSS Custom properties
:root {
— size-1: 0.8rem;
— size-2: 1rem;
— size-3: 1.3rem;
— size-4: 1.7rem;
— size-5: 2rem;
— size-6: 2.5rem;
— size-7: 3rem;
}
I then redefined the value of these variables when used inside a class called z400
meaning “zoom 400%”. Look how flat it is!
.z400 {
--size-1: 0.8rem;
--size-2: 1rem;
--size-3: 1.1rem;
--size-4: 1.2rem;
--size-5: 1.3rem;
--size-6: 1.5rem;
--size-7: 1.75rem;
}
I also added a media query for large screens too but that’s not too relevent.
I used JavaScript to determine the zoom level through a resize event listener. This meant I could add .z400
class to a container when the browser was zoomed 400%.
There’s stuff to do with zoom and device pixel density I haven’t figured out yet but that’s not the point, I just wanted to get something that kinda worked. On a retina device you only need to zoom 200% for this to kick in.
The output
I hate to only show these examples as images so you can view a quick CodePen demo here. Zoom in and see for yourself.
Example: Standard breakpoints — no zoom (100%) applied:
Example: large breakpoint with 200% zoom applied (on retina display).
The first example shows what would normally happen — everything gets bigger at the same ratio. The second example shows where I have overridden the type scale, only when zoomed.
You’ll see in the second example the scale is very flat. This potentially gives this a much better foundation for users that zoom. Remember my intent here is that a user can read both body copy and large headings without changing zoom levels or changing the way they read.
Going further
It could be beneficial to change font weight or style when zoomed too. People use different zoom levels because of the relationship of style, size and weight of the font, not just size.
For example, a thin font on a white background may need to be zoomed to a greater amount than a bolder font due to screen glare making it appear thinner.
Is it a good idea?
I’ve been thinking about this issue every day and I want to find out if it’s a rubbish idea or not so I just had to write this blog.
I’m convinced this must be a well trodden path, perhaps already discussed at length, perhaps not?
Have you observed this kind of user frustration?
Is there actually way to do this in CSS?
Is this going to cause issues when someone uses pinch zoom?
Is there a better solution?
Update
I’ve had as few great discussions since publishing this blog.
A few folks recommended looking into CSS clamp()
. This is not something I’d really used before and it certainly looks like something to explore further. Tools like Utopia by a few of the folks at ClearLeft take a lot of the complexity away.
In addition to this Adrian Bece’s exceptionally detailed article Modern Fluid Typography Using CSS Clamp on Smashing Magazine actually raises one of the same issues I have here — the inability to recognise and target when a browser is zoomed.
I also did some extra thinking for myself. Perhaps all we need is to think about a flatter type scale that exists below 360px. Not primarily intended for small devices, but for large devices over 400% zoom. I did consider if a combination of media queries might help here, up to 360px and landscape for example.
On top of this, I’ve had some great discussions with folks around assuming this is what people actually want. I have kicked off some conversations with users that use high levels of zoom and it’s clear that type scale is just one part of the equation. It’s always a combination of scale, weight, typeface and both foreground and background colour that affects both zoom rate and legibility.