Please help me understand mobile Safari's text resizing
Mobile Safari resizes some of the text by default, including <h1>
and <h2>
elements. I searched SO to see how I could prevent that and found questions such as these:
Font size issue with iPhone
Preventing iPhone scaling when rotated
font size change after orientation screen change to horizontal
Notice that the answer to all of those is the CSS property:
-webkit-text-size-adjust:none;
This works great for maintaining relative text size between header and paragraph elements on mobile Safari. However, I stumbled across a blog post just now titled Beware of -webkit-text-size-adjust:none:
What that does is prevent WebKit-based browsers from resizing text. Not even full page zoom resizes the text. Now, how can preventing your users from resizing text be a good idea?
According to Apple’s Safari CSS Reference (JavaScript required), -webkit-text-size-adjust "Specifies a size adjustment for displaying text content in Safari on iOS".
When given a value of “none”, the documentation specifies that "The text size is not adjusted".
Now, I took the property description to mean that the relative text size will not be automatically adjusted, not that the text size can't be adjusted by the user, but the author says that his testing shows that text indeed cannot be adjusted in WebKit-based browsers when a value of 'none'开发者_开发技巧 is specified.
(I am currently in a position where I am unable to verify this at all, but I am going to assume he and others who make the claim are correct.)
So my question is this: how can one gain control over the relative text size between headers and paragraphs in mobile Safari without sacrificing accessibility?
The key issue here, as I understand it, is when this rule is applied on its own - because when the value is 'none' it applies to any webkit browser, whether it's desktop, phone-sized, or tablet. Desktop webkit browsers don't apply any other value, as far as I can tell (-webkit-font-size-adjust:150%; does nothing).
When 'none' is applied to Mobile Safari on iOS, or any mobile Webkit browser (Android, etc), you get what feels like the 'right' effect: the browser doesn't try to adjust the font-size of some of your elements, and you (the designer) remain in control of their sizes relative to each other. You can still pinch/zoom and double-tap zoom to zoom in/out of the viewport. Mobile browsers do viewport scaling, not text-scaling.
However, when this rule applies to desktop webkit (Safari, Chrome), it feels wrong, because desktop webkit does do text-scaling, and this rule prevents that from happening.
So - the solution is to target only mobile webkit for this rule. CSS media queries are the logical answer for this, but managing to target all the iOS devices is a bit clunky and imprecise:
@media screen and (max-device-width: 480px),
screen and (-webkit-min-device-pixel-ratio: 2),
screen and (device-width: 768px) {
body {
-webkit-text-size-adjust:none;
}
}
This should get you all the iPhones up to the 3GS (1st rule), iPhone 4 (second rule), and iPad (3rd rule). The third rule should theoretically match desktop Safari too when the viewport is exactly 768px wide - but doesn't seem to in practice.
To be honest, I'm not sure it wouldn't be better to use javascript to detect mobile Safari and add a class to the body of the document to apply the rule. That way, you won't need to retro-fit new rules when devices with new displays come out.
Please pause to consider why Mobile Safari might want to resize your text. Mobile Safari (like Chrome for Android, Mobile Firefox and IE Mobile) increases the font size of wide blocks, such that if you double-tap to zoom in on that block (which fits the block to the screen width), the text will be legible. If you set -webkit-text-size-adjust: 100%
(or none
), it won't be able to do this, and so when a user double-taps to zoom in on wide blocks the text will be illegibly small; users will be able to read it if they pinch-zoom in, but then the text will be wider than the screen and they'll have to pan horizontally to read each line of text!
I listed possible ways of working around this in an earlier answer.
It seems that there was a parenthesis error in the accepted answer, causing this not to work in landscape mode.
Here is a corrected version:
@media screen and (max-device-width: 480px), screen and (-webkit-min-device-pixel-ratio: 2), screen and (device-width: 768px) {
body {-webkit-text-size-adjust:none;}
}
精彩评论