-
Notifications
You must be signed in to change notification settings - Fork 707
[css-inline] text-layout: glyph-bounding-box #2228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Should the browser position the large text in the above example screenshots consistently across OSs? Or could CSS offer a property? |
@litherum might have some insight on this... |
Just to clarify: I don't have a preference. I need consistent positioning (the same visual position) of large and medium-sized text in all browsers across all OSs. If that should and will be ensured by all browsers then that'd be fine with me. If instead (or eg for a specific category of fonts) CSS can and will offer some property that allows me to ensure this (and if all browsers then support it) then that'd be fine with me as well. |
I hope that the two screenshots show that the issue is quite severe in some cases. There are workarounds, but I hope that there will be a solution. |
Perhaps CSS could offer eg "text-metrics: platform-independent" or eg "text-position: platform-independent". No matter the name, I need a solution 😀 |
Rather than picking one metrics, I prefer to allow authors to set the length from the top of box to the baseline. If we consider this is for web fonts, it should solve, and it also solves some other cases I've heard of. |
If that would solve the issue I describe then yes that would be a good option. A detail: Let's say I work on a website/webapp on Mac OS. There's a large word on the page, and the spacing and layout is set just right for the visual text position. Now I want to ensure that the text stays in that same y-position no matter on which platform. I'd set the new property - but to which value? I'd have to measure the length from the top of box to the baseline on Mac OS before I could set it for all OSs. That measuring would be tedious eg if there are several web fonts. Instead I need a non-numerical value that ensures that the position of the text (of the glyphs) are always the same on all OSs. The workflow would then be simpler: Right away after setting up the webfont I'd set eg "position-of-glyphs: same-on-all-platforms". Then I'd set my spacing and layout based on that reliable text position. Then when I test the page/site/webapp on other OSs there'd be no issue regarding the position of the text / of the glyphs - the glyph position would be same in all browsers, on all OSs, and on all devices == there would be no mismatch with the spacing of my layout. What do you think? @kojiishi @FremyCompany @fantasai @litherum @dbaron |
In case it's helpful, here are the font metrics (via FontForge and the OS/2 table) for two of your examples:
Does this happen for all fonts? Do you get better results with line-height: normal or with less mixing of units? |
Thanks for caring!
To the extreme extent shown in the screenshots it happens to just a subset of the web-fonts I checked. But sometimes I do use fonts where it happens to that extreme extent, and for these cases it would be really great to have some (nice and quick to use) solution. It should be as easy as adding one line of CSS, without having to get the font metrics, for example 😀
Here's a version with line-height:normal and only em units (both regarding the h1): Screenshot of that page in Chrome on MacOS: Screenshot of that page in Chrome on Windows: |
Here's code from a website where I used a hack to compensate the difference in glyph-positioning: (Warning: it's from an older website of mine, uses jQuery 😮)
I think the horribleness of the above hack demonstrates that a solution is required 😀 |
In the above hack there's
and
So it seems that for that word & that font I had to apply x-axis compensation. I need a way to ensure that the glyphs in medium/large text get placed in the same position, regarding the x-axis and regarding the y-axis, in all browsers on all OSs on all devices. The property and value could be named eg "position-of-glyphs: same-on-all-platforms". (Sub-pixel differences are negligible. And: I never noticed an issue regarding the glyph positions in small text - just in medium/large text. Perhaps the property could be ignored for small text.) |
Is it inside the scope of the CSS WG to offer some solution for the (sometimes drastic) difference in large-text positioning across OSs? |
One question; what do you expect if font cascading or fallback occurs? Should the baseline position stay, or should it be adjusted according to the used font? |
I need a way to ensure that the glyphs in medium/large text get placed in the same position, regarding the x-axis and regarding the y-axis, in all browsers on all OSs on all devices. If the following tests pass, in all bowsers on all OSs on all devices, then the issue would resolved well enough as a first step. https://tobireif.com/non_site_stuff/test_case_for_font_position_report/ And (right away or later) consistent glyph-positioning should also be ensured for the cases you list. (I don't know what you mean by "font cascading", but I guess that both "font cascading" and "fallback" both mean that a different font is used eg until the respective web-font is loaded and applied.) The fix / the property should work for all fonts on all pages for any type of font, for fonts supplied via @ font-face, and for fonts loaded from the local system (eg "non-web-fonts") (including "-apple-system" and BlinkMacSystemFont). The default (eg in the absence of the new property) should be consistent glyph-positioning for all fonts used on a page, in all stages of the loading phase, in all browsers on all platforms (OSs and devices).
The glyphs should always get positioned in the same position (x-axis and y-axis, not just baseline) across platforms - per used font. |
Thank you, that was what I wanted to ask, sorry for not being clear. So in your use case, the position should change if the used-font is changed. |
No problem! Yep, I think that glyph positioning should always be correct - per font, and across all browsers/OSs/devices. |
It's hard to discuss this without understanding what's being done differently in different browsers. Are line layout rules from CSS 2.1 actually being violated? Is this only a problem with certain unusual font metrics? I don't have access to Windows, so it's hard for me to test. |
@tobireif Aside from specs, I've solved similar text-rendering inconsistencies by replacing text with svg text. -> http://jsbin.com/xequz/edit?js,output Here, control the sizes by altering the height/width of the |
While I agree to solve this problem, and I'm fine to put on F2F agenda, I think this will take some time to get to conclusion. fantasai and I had some early rough discussion last week, but we hope to solve similar related requests as well, and we need to design carefully about overflow, fallback, etc. The new property is likely to be added to CSS inline level 4, but we still have work for CSS inline level 3. The "per used font" is a bit challenging. I was hoping to solve one feature to solve two requests, but this makes it impossible. Re-thinking what the best feature would be. |
@dauwhe wrote:
Trying to reproduce the issue is a great first step! I use https://crossbrowsertesting.com/ - it's a great service for testing websites on many different device/OS/browser combinations. (I can not imagine doing web development without such a service - or a huge local device lab.)
I'm a web developer. The issue has been bugging me for years - I coded elaborate workarounds, and I hope that there will be a real solution for the future. I submitted the issue description including exact pixel measurements of the cross-OS difference of one case, provided three test pages, and eight screenshots. I should (and have to) leave the rest - including further investigations and including the solution - to the CSS WG and to the browser vendors.
I need consistent glyph positioning across OSs, browsers, and devices - no matter whether the font and it's metrics can be considered unusual or not 😀 |
Thanks for your input! That's a workaround, I had coded a different workaround, and there might be more options for workarounds. Now I need a solution 😀 |
@kojiishi wrote:
Sounds promising!
It would be a dream come true. Seriously. For me it is one or the main issues in web development (because many layouts contain large text) and the issue has been existing for many years, so a solution would be most welcome.
I'm confident that you and @fantasai etc can find a great solution. |
Adding a hack again in a current project 🙁
|
You are right that consistent font metrics across the Web are valuable. However, it is also true that it is valuable for a platform’s web browser to follow the platform conventions for font metrics. This is particularly important for Web Views inside native apps. It is very common for apps to use Web Views to draw content as-if it was native (and it should look like native content). Similarly, it’s impossible for the implementation of a Web View to know if a Web View being used by a particular app should have web-like font metrics or native-like font metrics. In addition, on a more pragmatic note, changing the metrics of every font used in a browser would change the layout of every website, which is super scary. |
This is undesirable. Browsers shouldn’t be required to have exactly compatible shaping engines and rendering engines. Consider a browser that is bundled with the OS - such a browser shouldn’t have to include its own independent shaping engine and font rasterizer that are only used for that browser and not for the rest of the OS (for reasons of binary size, performance, and correctness). There is industry competition in text engines, which is only possible if browsers have the freedom to innovate. |
With way too many. It's an issue in almost every project where large text is part of the design. (I always do testing across operating systems, devices, and browsers.) A test-page using the font Hetilica: A test-page using the popular font Frankfurter: Other fonts where the issue occurs include Ruritania, QuigleyWiggly, Scratch, and BigFish. And there are several StackOverflow pages which most likely are the tip of the iceberg.
I agree! They'd mean way too much work for the web developer, and for implementers. All I want is being able to opt into the same text-layout that browsers use for SVG text, for example
This line would set the same text positioning that browsers use for SVG. One line of CSS to type for the web developer, and for implementers it probably wouldn't be a lot of work because that text-layout has already been implemented for SVG text. And it wouldn't break any existing websites because it'd be opt in (via the new property).
Typical project deadlines don't leave time for requesting, awaiting, and hoping for a fix - for each used font. And some type foundries might never reply. And the license might not allow me to fix it.
The sad truth is that it's a widespread issue, and fixing each font is not feasible, thus a solution is required. Some designs feature many fonts. In one design (one single page) I had to compensate the text-layout for five(!) fonts (see the example in #2228 (comment) ). I'd much prefer it if every font would work well cross-platform, but alas that is not the case. All I want is being able to opt into the same text-layout that browsers use for SVG text, eg
or eg
Having such a property would mean that we could opt into text layout that's consistent across platforms without having to replace the HTML text with SVG text, without having to wait for font creators to fix each and every used font, and without having to compensate for the differences by applying OS-specific spacing. Instead we could opt into an already-implemented text-layout option where the glyphs stay in the same position across platforms. |
Wonder if #3240 could/would be used to also solve this per os issue? |
Yes, that is the intention. |
Any solution would be a big step forward for text in layout on the web! Keep us updated 😀 |
Or perhaps |
@tobireif you do realize that SVG text rendering is not the same thing as browser-based text rendering, right? They each have different features, advantages, and drawbacks. Your desire for browsers to "just be able to use SVG logic for non-SVG content" is a bit like asking for a car that could just use the same propellor as your boat. |
BTW it's almost surreal that the following article was published the very day I came across this issue. https://product.voxmedia.com/2019/6/17/18524029/the-ballad-of-drop-caps-and-design-systems |
I need consistent positioning of large and medium-sized text across operating systems. |
Regarding the article: It compares the rendering across browsers, not across operating systems. Their fix The issue is shown in the top post on this page here -> see the image below "Chrome on MacOS" vs "Chrome on Windows". |
General info: Related tickets with recent activity: |
I hope that this issue will get resolved soon. |
It would be great if this could get added to the agenda. |
I opened #4792 with the proposal I made in #2228 (comment) |
I finally got around to doing some proper testing. Here's what I believe is the algorithm for extracting ascent, descent and line-gap from OpenType fonts across several browsers: int ems = post.ems; // 1000, 2048 etc
boolean usetypo = (os2.fsSelector & 128) != 0; // USE_TYPO_METRICS
int ascent; // distance from text-top to baseline; positive
int descent; // distance from text-bottom to baseline; negative
int linegap; // add to ascent and -descent to get default line-height
if (safari_on_mac || chrome_on_mac || safari_on_ipad || chrome_on_ipad) {
ascent = hhea.ascent;
descent = hhea.descent;
linegap = hhea.linegap;
} else if (firefox_on_mac || chrome_on_linux || chrome_on_android || edge_on_android || samsung_on_android || prince || bfo) {
ascent = usetypo ? os2.sTypoAscender : hhea.ascent;
descent = usetypo ? os2.sTypoDescender: hhea.descent;
linegap = usetypo ? os2.sTypoLineGap : hhea.linegap;
} else if (firefox_on_linux || firefox_on_android) {
ascent = usetypo ? os2.sTypoAscender : hhea.ascent;
descent = usetypo ? os2.sTypoDescender: hhea.descent;
linegap = os2.sTypoLineGap;
} else if (chrome_on_windows || firefox_on_windows || edge_on_windows || ie11) {
ascent = usetypo ? os2.sTypoAscender : os2.usWinAscent;
descent = usetypo ? os2.sTypoAscender : -os2.usWinDescent;
linegap = usetypo ? os2.sTypoLineGap : hhea.linegap; // note ie11 puts all linegap after line.
}
if (firefox) {
if (linegap == 0 && ascent - descent <= ems) {
if (usetypo || !firefox_on_android) { // apparently, according to crossbrowsertesting.org
linegap = ems * 1.2 - ascent + descent; // line-height always 1.2em
}
} else if (ascent - descent < ems) {
linegap += ems - ascent + descent;
}
} I'd hoped to show exhaustive working in one place, but the testing got a bit out of hand and there are just too many combinations! Plus some of this I'd already established so didn't need to retest. I didn't test anything really weird (e.g. -ve ascents) and I haven't fully confirmed the firefox "fix up the line-gap" algorithm is the same on all platforms. So there's undoubtedly more to this, but I think it's pretty close. (Edit: updated to add prince, our renderer, and some other results according to http://crossbrowsertesting.org) |
I've made a hopefully coherent demonstration of this at https://bfo.com/misc/metrics/ - it doesn't demonstrate the firefox "fix-up the line gap" algorithm, but does show the special handling when linegap==0 |
Fwiw, Gecko's normal computation is in GetNormalLineHeight |
Aha! Thank you @fantasai. So the "fix up the line gap" constant is NORMAL_LINE_HEIGHT_FACTOR |
Finally there's a great solution for the issue where browsers display large text at different vertical positions across operating systems: font metrics overriding. Check out my post: I'm leaving this ticket open, because having eg |
I need consistent positioning of large and medium-sized text across operating systems.
The large text on the page
https://tobireif.com/non_site_stuff/test_case_for_font_position_report/
gets positioned differently eg in Chrome on Mac vs in Chrome on Windows:
The space above the large text is 102px in Chrome on Mac
vs 125px in Chrome on Windows.
The space below the large text is 75px in Chrome on Mac
vs 52px in Chrome on Windows.
Another test-page:
https://tobireif.com/non_site_stuff/test_case_for_font_position_report_yet_another_font/
From the above test-page:
Chrome on MacOS:
Chrome on Windows:
The large-text positioning / the space above and below the large text should be the same across operating platforms, for this font and for all fonts where the effective position currently is different across operating systems.
In order to not break existing content there needs to be a new CSS property,
eg
position-of-glyphs: consistent-across-platforms;
or eg
text-layout: glyph-bounding-box;
(The latter would set the same text positioning that browsers use for SVG.)
There are many other pages/sites/layouts where medium/large text and its position is important.
I need a way to ensure the same vertical text position across platforms.
The alternatives are not great:
a) Applying spacing:
eg
This is a hack.
b) Fixing each problematic font:
This is not always feasible: There might be no time to do this, many web devs use fonts hosted by external services, and thirdly the font license might not allow any modifications.
c) Using SVG text instead of HTML text:
Replacing each respective text with SVG has major drawbacks: Some might fear that it might impact eg search engine visibility. Imagine a newspaper considering to use SVG for its headlines while search engines handle h1/h2/etc well - they probably wouldn't take that risk. And it might also impact accessibility, see https://www.google.com/search?q=svg+text+screen+readers . It's a potential issue as far as I can see (eg in a given specific screen reader), while HTML text can be expected to just work. Also, SVG is meant for graphics (which might contain text or not) - a pure text page (eg an article) coded in HTML shouldn't have to use SVG just to get consistent cross-OS text-layout (for its large text instances).
Thus it would be great if consistent cross-OS text-layout would be available in HTML as well (not just in SVG as is currently the case).
I hope that CSS will support opting into the glyph-bounding-box-based layout (which browsers already have implemented for SVG) as option for (typically large) HTML text.
eg
h1 {text-layout: glyph-bounding-box}
or
h1 {glyph-positioning: glyph-bounding-box}
(The exact names for the property and value could be different.)
That would solve the issue completely.
The text was updated successfully, but these errors were encountered: