Font size value scaling with browser zooming - css

I have found an issue which is causing me some confusion. I have font-sizing set across my CSS file with rem scaling, and a base font size of 16px set in the html{ ... } block in the CSS file.
My Issue
When scaling the browser using the browsers own zoom method (Firefox v46 in this case. I have also done this with Chrome v51) the text on the website changes size just fine, however, various padding and a few other elements have scales relating to the font-size, rem value, yet viewing the computed and source code with Firebug (and with Chrome inspector), does not show a zoom-adjusted computed change in these values in px, even when zoomed.
For example:
CSS:
html,body {
font-size: 16px; /*the base.*/
}
nav {
font-size: 0.75rem; /* should be 12px */
}
.textBlock {
font-size: 0.95rem; /* should be 15.2px */
padding: 0 0.15rem; /* should be 2.4px */
}
Now, when I load the page at 100% zoom, everything shows at scale and all computed values are as commented. But if I increase the zoom, for example to 120%, everything textual on the page increases in size proportionally, (while non-font-size-related elements stay consistent), but then reading the page source with firebug, it still tells me that:
code view:
html, body {
font-size: 16px;
}
.textBlock {
font-size: 0.95rem;
padding: 0 0.15rem;
}
Computed results
font-size: 15.2px (in textBlock).
padding: 2.4px (in textBlock).
I want to be able to view the computed size of the elements on the page taking into account the zoom value .
I was under an impression that by changing the zoom of the browser that it altered the body (or html) element base font-size, so that 1rem computed value changes from 16px to 17.5px (for example), and that due to this all related child elements would scale appropriately.
The fonts do scale but I as a browser user I get no feedback on to the current output size of the font based elements on the page.
Further Testing
Using javascript (from this answer) also tells me font size is 16px in the main body, regardless of zoom.
Deleting the body font size does not change anything.
Setting the base body font size to a rem/em value also does not change the feedback given by Firebug, Javascript or Chrome Inspector.
Why don't I read the other font-size questions on StackOverflow
All other (and there are quite a few) font sized questions that I've found relate to people putting static values such as 14px as their element sizes and expecting them to scale.
I can find no useful literature (since 2008/09) about how the browsers actually work the zooming mechanism and how developers can work with this tool.
What Am I trying to achieve/find
I want to be able to view the webpage at any browser zoom level and be able to detect and get feedback telling me the size of the font-size value on various elements, such as:
Zoom 120% on .textBlock [computed] {
font-size: 18.24px; /* (16px * 1.20) * 0.95 */
padding-left: 2.88px; /* (16px * 1.20) * 0.15 */
padding-right: 2.88px; /* (16px * 1.20) * 0.15 */
}
This is more important in my own case for measuring paddings as they're often also rem based in my situation (I am finding that some elements are overflowing due to browser zoom not being 100%). But regardless of my own requirements, I am very surprised that I can't seem to find the computed values I would feel would be pretty basic to need. I want to fix this (and to be honest I can fix my own CSS easily enough, but I wanted to get feedback from reading what the computed font size is, after zoom, but found the issue I post here).
Basically, I want to be able to get quantitive feedback of computed CSS values from a website based on the browser zooming value, of the rem scalar value.
Are there Any solutions to this?

First of all, the rem unit is related to the root element, i.e. html, therefore, changing font-size on body does not have any effect on the descendant elements.
Firebug and the other developer tools display the computed values according to the W3C specification. More precisely, they use the window.getComputedStyle() function to get the computed value and this function does not take the zoom level into account.
To get the actual font size, you need to calculate it yourself. How you do that is described by Tom Bigelajzen. He also created a script to detect the zoom level.
With it you should be able to calculate the actual font sizes by multiplying the computed font size with the zoom factor:
var cs = window.getComputedStyle(element);
var actualSize = Number.parseFloat(cs.fontSize) * detectZoom.zoom();

you can use the pixel ratio to determine the zoom level the user has set it at for example : works in chrome , firefox, edge and brave browser
#media only screen and (min--moz-device-pixel-ratio: 1.25),
(-o-min-device-pixel-ratio: 5/4),
(-webkit-min-device-pixel-ratio: 1.25),
(min-device-pixel-ratio: 1.25) {

Related

Is there anything wrong with html {font-size: 1px;} for working with REM units?

html {font-size: 62.5%;} seems like the standard approach to set the base font-size to 10px.
E.g.,
html {font-size: 62.5%;} /* 10px */
body {font-size: 1.5rem;} /* 15px */
But this creates a dependency on the browser's font-size 16px. This seems unreliable in the long run... why not just...
html {font-size: 1px;} /* 1px */
body {font-size: 15rem;} /* 15px */
Is there a technical problem with this? It seems cleaner and much more reliable. Why don't I see people do this?
Once upon a time, there was IE and text scaling only. Other browsers came and abandoned the concept in favor of scaling the whole viewport. After all, if you're having a hard time reading the text, you probably have a hard time seeing images and other non-text elements too.
When you're working with relative font-sizes, at some point they have to be converted to the base pixels on the screen. The default modifier is by and large expected to be 16px, you can imagine it as a declaration on an element 1 level above <html>. Any base modifications, like 62.5% on the body for 1 relative unit to equal 10px, scale off that value.
With that in mind, what you're effectively doing is taking matters into your own hands, overwriting the browser base font-size above <html> and setting it to 1px value instead, resulting in 1 em/rem being always equal to 1px inside the body. However, there is a price - the browser is no more able to propagate it's own base font value because of your direct pixel value, so any font-size settings the user may have set are neglected by your declaration. In other words, using the 1px trick disables the pure font-size zoom of the browser. At the same time however, font-size only scaling remains fundamentally flawed in it's intention (look at google.com results with scaled font).
If you'd like to retain the ability of the browser to control the font-size only zoom AND at the same time work with 1rem = 1px, you probably want this instead. edit: I should note that this will be problematic in Chrome due to the minimum font size settings (6px default). Paddings and margins will scale off this value as minimum.
html {
font-size: 6.25%;
}
body {
font-size: 16rem;
}
In 2020, you can do this in Chrome by going to:
chrome://settings/fonts
then slide the minimum font size from 6px to 0.
Now, Chrome won't override the minimum of any font size.

Is there a CSS trick to obtain a default font size on all devices

Is there any system independent way in CSS to obtain a standard-text font size from the browser, something that would be suitable for, say, a blog post?
I thought that em would do this, but when I set font-size : 1 em; I get a standard text font size on desktop and something extremely small on mobile.
I understand that sometimes the true DPI might be unknown to the OS. But on a mobile device, shouldn't the browser have some rough idea of how big readable text has to be? And shouldn't there be a way to obtain this information?
If you want the standard system font size, you'd just do this in your CSS:
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
}
It's a best practice to define your font sizes in relative units (percentage, em) whenever possible so that they scale appropriately according to the target device's built-in settings.
If you're using em's then you first need to define a base value for the font. Ex.:
body { font-size: 16px }
Now 1em = 16px.
Most browsers have a default user-agent font-size of 16px but you shouldn't rely on it. Set the base value then start using em's.

Compounded relative font-sizes: a clean way to adopt the font-size of the child, not the parent element

For example, if I have:
td { font-size: 1.3em }
h2 { font-size: 2em }
h3 { font-size: 1.6em }
p { font-size: 1.2 }
And I have headings/paragraphs inside my table-cells, I know that I can avoid compounding the font-sizes by the following:
td h2, td h3, td p { font-size: 1em }
Which would result in the headings/paragraphs in my table-cells having font-size of 1.3em (that of the td).
But what I'm looking for is a nice, clean way for each child element to have it's original font-size, not that of the parent.
I'd really like to avoid doing the following (and of course I'd like to avoid using px):
td h2 { font-size: 1.54em } // 1.3 x 1.54 ~ 2
td h3 { font-size: 1.23em } // 1.3 x 1.23 ~ 1.6
td p { font-size: 0.92em } // 1.3 x 0.92 ~ 1.2
For anyone familiar with LESS, I'm using that, and thought I should be able to use it to do the calculations for me, e.g. Using accessors:
td h2 { font-size: h2['font-size'] / td['font-size'] }
This at least would use the original values to do the calculation but feels just as clumsy as the above and besides, it seems LESS no longer supports accessors anyway.
This seems so simple in concept, I feel like the answer's staring me in the face, but I've been banging my head against this for a while and can't find the answer anywhere.
What you want can be achieved by using rem units.
rems are relative ems which base their calculations on the font-size declared on the body element.
Compounding issues simply disappear.
http://snook.ca/archives/html_and_css/font-size-with-rem is an excellent article to articulate this.
note: IE8 requires a px fallback, but this won't be an issue since you're already making use of a preprocessor.
EDIT: I've written a Sass mixin which outputs rems with their respective px fallbacks for most CSS properties:
https://gist.github.com/larrybotha/4153104
I'll answer the same as my question, use Pixels!
A pixel is a relative unit, it's relative to the screen resolution, users can set their own desired minimum pixel size, and zoom zooms pixels. I'd venture that it is more difficult for a designer to approximate non pixel font-sizes at every perceivable resolution than it is to relax and let the browser tools take care of it?
It used to be that a font declared in pixels wouldn't resize in IE which was very annoying for some, not very accessible if a user deliberately chose to view on a lower resolution for instance for eyesight reasons - that's where the "em's were best for fonts" thing came from, but that was never true IE could be foiled using percentages instead which then offers the same problems ;).. I remember getting annoyed when the fad was for "teeny text", but then the joys of discovering CTRL+ in non-ie .. anyway now the pixel sized fonts will scale perfectly well, if you're building a fluid site you can build it with a mixture of em's for widths and pixels for font-sizes - if it looks OK at your resolution try zooming it, both up and down - you have to go pretty far up or down before it becomes illegible, and who's zooming it that far up/down except designers ;)
Have you considered adding a class to the headings that are in table cells? The extra level of specificity would override the effect of the cascading styles compounding each other, I think.

body { font-size: 100.01%; } vs body { font-size: 100%; }?

What should i keep for body, {font-size: 100.01%; } or { font-size: 100%; }?
what is {font-size: 100.01%; }? and is it really good to mention font-size in html{} even
If I'm using body {font-size: 62.5%;}
Edit : 3 May 2010
Today i found info about 100.01% at here - http://www.communitymx.com/content/article.cfm?cid=FAF76&print=true
This odd 100.01% value for the font
size compensates for several browser
bugs. First, setting a default body
font size in percent (instead of em)
eliminates an IE/Win problem with
growing or shrinking fonts out of
proportion if they are later set in
ems in other elements. Additionally,
some versions of Opera will draw a
default font-size of 100% too small
compared to other browsers. Safari, on
the other hand, has a problem with a
font-size of 101%. The current "best"
suggestion is to use the 100.01% value
for this property.
Is it good to keep body { font-size:100.01%} in place of {font-size:100%}
The declaration body (or html) { font-size: 100.01% } compensates rounding errors, in particular in older versions of Opera and Safari. Both would otherwise display fonts that are too small.
A relative font-size (%, em) is always interpreted relative to the font size of the parent element. So it's not a bad idea to implement kind of a initial reset in the top element, which you can achieve with body {font-size: 100%}.
Never seen 100.01% before, but it seems like some sort of browser hack that will force some browsers to ignore or calculate size correct if you use this "fix".
I wouldn't use it myself though, as errors tends to be fixed and there are often more nice ways of dealing with the same option.
html {
font-size: 100.01%;
}
100.01%, not a hack or a kludge, has been around for many years. Google "100.01%" and read up. It is as valid as 100% and does cover some territory 100% doesn't.
An initial font-size should always be declared. Set a base font-size on an outer container -- either <html> or <body> -- for it is from that container which all relative and inherited font-size values will derive. Using 100% or 100.01% makes the starting font-size equal to the user's browser preference.
Setting that base font-size to the user's browser preference gives your visitors maximum readability. Read that again, please, about the USER's preference. Your visitor will have set their browser font-size for their own best legibility and reading comfort. Your design, magnificent and fragile though it may be, is only a second-string player. Content is king, assuming you have some. But if that content is un-readably tiny, you lose. The visitor surfs on. Your design, then, has failed your needs and your expectations. Therefore, the design really wasn't all that great, was it?

Ems to Pixel Conversion - Why 62.5% and not 6.25%?

I know that a lot of us are familiar with setting the font size on the body element in our CSS to 62.5%. This means that 1em will equal 10px and helps for keeping things pixel perfect but also allows for scaling of fonts.
So wouldn't that mean that setting it to 6.25% would equate to 1em = 1px? Seems like an even simpler conversion rather than having to mess with decimals...
Thanks guys! I'm quite aware of the em and it's history (design degree), but I'm sure others may find it helpful :)
As far as the 1em = 1px, I don't see how this is undesirable. The em is square, regardless of your units (be it points or pixels) and nobody would set their type at 1px (just like nobody would set printed type at 1pt). Furthermore, even your article concedes that in most digital typefaces, the capital "M" is usually smaller than 1em, and that the em is merely a reflection of the point size (48pt type would render a 48pt by 48pt square for the em, 12pt type would yield 12x12, etc.)
Besides, the reason people would do this would be more for setting dimensions of other elements on the page so that everything scales nicely when the user adjusts their font size. Sure, there will always be the rare few who set their default to something other than 16px, but well worth the price to pay for a pixel perfect layout that scales nicely.
First of all, do not assume that 1 em will equal 10 pixels. An em unit is in direct correlation to the typography being used. If someone has a font size of 16 pixels, then 62.5% is indeed 10 pixels (16 * 0.625 = 10) but this will obviously change when someone has modified their default font size.
Secondly, this is the first I've ever heard of using 62.5% for the base body font-size. I always use a font-size of 76% as based on Sane CSS Typography by Owen Briggs.
Lastly, to answer your question, yes you could use a font-size of 6.25% and then use 12em instead of 1.2em, for example. However, I would highly discourage this methodology. In the world of typograhy, one em is intended to be the width of the capital letter 'M'. This method completely violates that common practice and will seriously confuse anyone that may maintain your CSS in the future.
Arguably, but then you lose control over your scale. Don't forget that headings will typically inherit those same sizes in proportion to their rank (i.e. <h1> will be largest, <h2> slightly smaller). If you want to decrease those elements, you will need to use em values with a lot of decimal placeholders. Imagine <h4> font-size: 0.005em.
Or worse, if you want fonts to be scaled larger, you could potentially be looking at font-size: 40em or something ridiculous.
In short, 1em = 10px is much more practical for the scaled values of fonts. While a 1:1 scale might make sense on paper, it doesn't lend itself that well to sensible and maintainable CSS.
The conversion may be simpler, but an em wouldn't mean what it is supposed to mean.
1em is supposed to be equal to the width if a capitalized "M" in a given font. If the width of the letter M is 1 pixel, your font is going to be unreadable.
http://en.wikipedia.org/wiki/Em_(typography)
The whole "62.5%=10px" thing is fundamentally broken anyway - 62.5% may or may not be 10px depending on the browser, the user's settings, and, especially, the minimum font size setting. So you can't just design in pixels and then "convert" to ems on the assumption that 62.5%=10px, because your design will break all the time. If you want a pixel-perfect design, you have to use pixels as the unit. If you want a flexible design, you need to think about the appropriate units for different elements of the web site - ems for elements which should scale relevant to text size, percentages for elements that should scale relative to window size, and pixels for elements (like images) that shouldn't scale at all.
Anyone who includes font-size: 62.5% in their CSS fundamentally doesn't understand how to design for the web.
Great question.
I see 6.25% as an interesting proposition for adaptive / responsive web design and elastic templates.
In particular font sizing with rem unit's lends it's self to your argument... a 1:1 ratio is just easier.
rem: "root em"... the font size of the root element.
http://www.w3.org/TR/css3-values/
See this rem example from: http://snook.ca/archives/html_and_css/font-size-with-rem#c67739
html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */
And now with your suggestion...
html { font-size: 6.25%; } /* 1em = 1px if browser has 1em = 16px */
body { font-size: 14px; font-size: 14rem; } /* =14px */
h1 { font-size: 24px; font-size: 24rem; } /* =24px */
... Play with my JSBin example: Testing CSS3 "rem" Units for Elastic Content
A 1:1 em to px ratio should lead to less typos.
REM Notes: With proper CSS resets and body declaring the base font-size in both px and rem your styles degrade gracefully... If rem is supported, and declared after px, it's value is applied. Otherwise the browser falls back to px.
Determining support (especially on mobile) for rem. Please hit this page with any/all browsers/devices you can... http://ahedg.es/w/rem.html
I tried to do the same thing, but ran into an issue of using rems for margins and paddings. Setting font-size to 62.5% avoids these issues.
For example, the following CSS
html {
font-size: 6.25% /* 16px * .0625 => 1px */
}
p {
font-size: 1rem;
margin: 1rem;
}
renders as:
p {
font-size: 1px;
margin: 9px; /* WTF?! */
}
Strange, right? I'm assuming this is caused by some odd conflict with minimum font sizes.
Now, if you use font-size: 62.5% on the other hand, things render as expected:
html {
font-size: 62.5% /* 16px * .625 => 10px */
}
p {
font-size: .1rem;
margin: .1rem;
}
renders as:
p {
font-size: 1px;
margin: 1px;
}
You might find this useful as well. http://pixel2em.kleptomac.com
This provides an online pixel to em converter and you can also do a complete CSS file conversion.
An updated version is available at http://pixelconverter.kleptomac.com
Its an online unit converter for converting pixels, point, em, percentages. This supports conversion from/to any of these units.
For anyone who arrives at this useful post, I would like to share a link for a youtube video (approx.48 min.) about good web typography. It's actual and gives everyone a significant insight that changes the way you set type for the web.
I just made some subtle changes based on this conference video, and the results achieved were perceived, even by our users, as surprising.
The presentation is from Richard Rutter, and the link for the presentation is Richard Rutter | Web Typography

Resources