Open Bug 1903360 Opened 8 months ago Updated 8 months ago

getComputedStyle(node).fontSize ignores the minimum font size configured by the user

Categories

(Core :: DOM: CSS Object Model, defect)

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.

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.

Severity: -- → S3
OS: macOS → All
Hardware: x86_64 → All
Version: Firefox 127 → Trunk
Attached file testcase 1

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.

(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 shows establishes 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.

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.

(ticking 'needinfo' to satisfy curiosity about use-case.)

Flags: needinfo?(nicolo.ribaudo)

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 :)

Flags: needinfo?(nicolo.ribaudo)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: