{"id":2356,"date":"2024-05-22T14:18:08","date_gmt":"2024-05-22T20:18:08","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=2356"},"modified":"2024-05-22T14:18:10","modified_gmt":"2024-05-22T20:18:10","slug":"danger-preventing-zoom-from-changing-text-size","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/danger-preventing-zoom-from-changing-text-size\/","title":{"rendered":"(Danger!) Preventing Zoom from Changing Text Size"},"content":{"rendered":"\n<p>Zooming in browsers is an accessibility feature. I&#8217;d say that any attempt to fight against it is bad form. Don&#8217;t do it. Leave it be. <\/p>\n\n\n\n<p>I have seen<a href=\"https:\/\/ashleemboyer.com\/blog\/why-you-should-use-px-units-for-margin-padding-and-other-spacing-techniques\"> compelling examples of ways to code<\/a> that work <em>with<\/em> browser zoom that help make a site look nicer when high levels of zoom are applied. But they don&#8217;t fight against it. <\/p>\n\n\n\n<p>You might say: <em>but I zoomed my site in to 500% and it looks bad! <\/em>It might, it&#8217;s true. But that&#8217;s just, like, <em>your opinion<\/em>, man. Zoom works consistently. People that use it know what it does. They know what to expect. They aren&#8217;t you, they might have a different approach an expectation than you do. <\/p>\n\n\n\n<p>I wanted to write all that before I share this snippet. This is a variation of what someone sent me the other day as a way to size type that scales with the window:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">html<\/span> {\n  <span class=\"hljs-attribute\">--size-factor<\/span>: (<span class=\"hljs-number\">0.00188323<\/span> * <span class=\"hljs-number\">100vw<\/span>);\n  <span class=\"hljs-attribute\">font-size<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">12<\/span> * var(--size-factor));\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Their version was a bit more exotic, incorporating different scaling numbers for pages in landscape vs. portrait and such. This has the effect of &#8220;fluid type&#8221; on a website, the bigger the window, the bigger the type, and vice versa. The magic number you see above there is essentially so that that you can multiply against it with reasonable numbers that maybe feel something close to pixel (<code>px<\/code>) numbers, <code>12px<\/code> in this case. In that way, it&#8217;s a lot like the <code>font-size: 62.5%;<\/code> thing we used to see a lot such that the math works out that <code>1.2rem<\/code> would be <code>12px<\/code> (you can do it in your head easier). I&#8217;d suggest scrapping that thinking. Don&#8217;t think about font sizing in pixels at all \u2014 it isn&#8217;t useful.<\/p>\n\n\n\n<p><strong>What is ultimately going on here though is that the <code>font-size<\/code> is being set in viewpoint units only. This is what &#8220;fights&#8221; the browser zoom.<\/strong> I could have done <code>html { font-size: 3vw; }<\/code> and the effect would have been basically the same.<\/p>\n\n\n\n\t\t<figure class=\"wp-block-jetpack-videopress jetpack-videopress-player\" style=\"\" >\n\t\t\t<div class=\"jetpack-videopress-player__wrapper\"> <iframe title=\"VideoPress Video Player\" aria-label='VideoPress Video Player' width='500' height='239' src='https:\/\/videopress.com\/embed\/ZsEZlh2G?cover=1&amp;autoPlay=0&amp;controls=1&amp;loop=0&amp;muted=0&amp;persistVolume=1&amp;playsinline=0&amp;preloadContent=metadata&amp;useAverageColor=1&amp;hd=0' frameborder='0' allowfullscreen data-resize-to-parent=\"true\" allow='clipboard-write'><\/iframe><script src='https:\/\/v0.wordpress.com\/js\/next\/videopress-iframe.js?m=1674852142'><\/script><\/div>\n\t\t\t<figcaption>The reason you see any shift at all here is that the body&#8217;s default margin of 8px is scaling up with the zooming.<\/figcaption>\n\t\t\t\n\t\t<\/figure>\n\t\t\n\n\n<p>Bad news bears.<\/p>\n\n\n\n<p>The advice: any time you are setting a <code>font-size<\/code>, it <em>cannot only be viewport units.<\/em> It has to factor in some other kind of unit. Heck, even <code>px<\/code> works to maintain some scaling. Even this freaks me out a little bit because it affects that rate of scaling and if you speed that up or slow that down too much, that&#8217;s also messing up with the natural exceptions of how zoom works.<\/p>\n\n\n\n<p>The best approach that I know of is to use <code>clamp()<\/code> so that <code>font-size<\/code> can&#8217;t get too big or too small based on window size alone, then include a <code>rem<\/code> value (that&#8217;s somewhere in the vicinity of 1) in the calculation such that zooming still works normally.<\/p>\n\n\n\n<p>See the <a href=\"https:\/\/www.fluid-type-scale.com\/\">Fluid Type Scale<\/a> website for easy to generate snippets.<\/p>\n\n\n\n<p>And this goes for using container units too! <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Zooming in browsers is an accessibility feature. I&#8217;d say that any attempt to fight against it is bad form. Don&#8217;t do it. Leave it be. I have seen compelling examples of ways to code that work with browser zoom that help make a site look nicer when high levels of zoom are applied. But they [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2361,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[49,7,39],"class_list":["post-2356","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-accessibility","tag-css","tag-typography"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/05\/image-4.png?fit=1792%2C1024&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=2356"}],"version-history":[{"count":4,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2356\/revisions"}],"predecessor-version":[{"id":2365,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/2356\/revisions\/2365"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/2361"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=2356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=2356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=2356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}