getComputedStyle(node).fontSize ignores the minimum font size configured by the user
Categories
(Core :: DOM: CSS Object Model, defect)
Tracking
()
People
(Reporter: nicolo.ribaudo, Unassigned)
References
Details
Attachments
(2 files)
getComputedStyle(node).fontSize
should return the font size used to render the font inside the element, rather than what was specified via CSS. These two almost always match, except when a user sets a minimum font size in their settings.
To reproduce, go to "about:preferences#general
> Fonts > Advanced > Minimum font size" and set it to some value. Then, run this script:
const div = document.createElement("span");
div.innerHTML = "aaa";
div.style.fontSize = "1px";
document.body.append(div);
const minSize = getComputedStyle(div).fontSize;
div.remove();
console.log({ minSize });
In Firefox it logs 1px
, while in Chrome/Safari it logs the value set by the equivalent of the "Minimum font size" option. I couldn't find what the specification says about this case, but it'd be good to match the behavior of the other browsers.
Comment 1•8 months ago
|
||
Thanks for the bug report! I can reproduce the difference vs. e.g. Chrome here. (For reference, Chrome's minimum font size setting is at chrome://settings/fonts
.)
The font-size
property is a bit special since it doesn't just get used for text, but it also establishes the value for em
and rem
units, and we don't want the "Minimum Font Size" value to mess with those units (e.g. 2em
shouldn't be interpreted as 2 * minimumFontSize
; fortunately it seems no browser actually does that). So we have to be careful with processing the computed font-size
; it's not as simple as just scaling it up directly in the style-system.
It looks like all browsers do handle em
units correctly in this respect, though. Arguably Firefox's behavior is a bit less magical (and hence more predictable?) since 1em
yields the same computed value regardless of whether it's in the font-size
property vs. in some other property. But maybe the other browser behavior (reporting the actually used value) is more useful? Not sure. I'm guessing they do implement this as a hack in their getComputedStyle
implementation, though.
Spec-wise, the authoritative spec text is here:
https://drafts.csswg.org/cssom/#resolved-values
For certain properties, this spec section defines special getComputedStyle behavior (often the "used value", i.e. the value-used-for-layout, with percentages resolved etc) for some properties. The default behavior there ("Any other property" at the bottom) is to return the actual Computed Value, which is the value that would inherit (which in this case is the raw value, 1px
etc). So in that respect, Firefox is matching the spec text here.
Comment 2•8 months ago
|
||
Comment 3•8 months ago
|
||
Here's a screenshot of Firefox vs. Chrome on testcase 1, with a minimum font-size of 10px in the browser settings.
(note, "computes to..." in my testcase should really say "produces a getComputedStyle result of...")
In Firefox, you can see that the reported font-size is the unclamped value, and matches what we use for resolving em
units on children (it matches the value reported for "establishes an em unit of:`).
In Chrome, you can see that the reported font-size is the clamped value (always 10px
for the values that I tested here); but the value used for em units is unclamped and matches Firefox.
Comment 4•8 months ago
•
|
||
(In reply to Daniel Holbert [:dholbert] from comment #1)
Thanks for the bug report! I can reproduce the difference vs. e.g. Chrome here. (For reference, Chrome's minimum font size setting is at
chrome://settings/fonts
.)
Filling in Safari details for completeness (Safari 17.5):
- The relevant minimum-font-size setting is In Safari Preferences, in the "Advanced" tab -- it's the first checkbox next to Accessibility there, with label "Never use font sizes smaller than [...]"
- Their behavior is different from Chrome! For them, the minimum font-size does seem to influence their
em
sizing. If I load my testcase with a minimum font-size of 10px, the console output showsestablishes an em unit of 10px
for every single section; and all of the blue rects look visually the same width -- they're all 10px wide, instead of having the width of the raw font-size value.
Comment 5•8 months ago
|
||
Out of curiosity, what is your use-case for this getComputedStyle
behavior? (Are you trying to find out if users have a minimum font size set? And if they do, what sort of things would you do differently?)
In any case, I filed https://github.com/w3c/csswg-drafts/issues/10479 to consider whether to update the spec to incorporate this clamping in getComputedStyle.
Comment 6•8 months ago
|
||
(ticking 'needinfo' to satisfy curiosity about use-case.)
Reporter | ||
Comment 7•8 months ago
|
||
Thanks for all the details! I'll subscribe to the spec issue.
The reason I needed this was for a bugfix in PDF.js. It renders some text in a canvas (that is not affected by the minimum font size), and then it render some transparent HTMl text on top to support text selection. This text on top must match the font size in the underlying canvas, and thus it must revert the "minimum font size" effect (since it's transparent, it being bigger doesn't make it any more readable anyway): https://github.com/mozilla/pdf.js/pull/18283
I found a different way to detect the minimum font size, by getting the height of a block element that has line-height: 1
, but it'd still be nice to have the three browser align in their getComputedStyles
behaviour :)
Description
•