| Summary: | REGRESSION(r281389): Text wraps unnecessarily within intrinsically-sized elements when using certain fonts and the inner HTML of the element contains a new line that is not preceded by a space | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | WebKit | Reporter: | Oliver Byford <oliver.byford> | ||||||||||||||||||
| Component: | Layout and Rendering | Assignee: | Myles C. Maxfield <mmaxfield> | ||||||||||||||||||
| Status: | RESOLVED FIXED | ||||||||||||||||||||
| Severity: | Major | CC: | bfulgham, ews-watchlist, mmaxfield, simon.fraser, vanita.barrett, webkit-bug-importer, zalan | ||||||||||||||||||
| Priority: | P1 | Keywords: | InRadar | ||||||||||||||||||
| Version: | Safari Technology Preview | ||||||||||||||||||||
| Hardware: | Mac (Intel) | ||||||||||||||||||||
| OS: | macOS 11 | ||||||||||||||||||||
| Bug Depends on: | 234428 | ||||||||||||||||||||
| Bug Blocks: | |||||||||||||||||||||
| Attachments: |
|
||||||||||||||||||||
|
Description
Oliver Byford
2021-11-10 04:11:34 PST
Created attachment 443799 [details]
Safari Tech Preview r132
Created attachment 443800 [details]
Safari Tech Preview r134
Created attachment 443801 [details]
Safari Tech Preview r132 – using Arial
From further testing, this appears to be an issue when:
- using certain fonts – it happens with our font ('GDS Transport'), but not Roboto
- an element is intrinsically sized (e.g. `display: inline-block`)
- there is at least one new line anywhere within the inner HTML of the element – unless there is a space immediately before the new line
See https://codepen.io/36degrees/pen/abyjzNr for a minimum viable example of the issue.
Thank you for reporting it. I can reproduce it. Will look into it shortly. This is caused by the -#if !USE(FREETYPE) +#if PLATFORM(WIN) changes in r281389. Maybe it made an existing bug in our layout/text code visible. This is a really bad bug and we should fix it immediately. Also, this is a fantastic bug report. I don't know if I've ever seen a bug report this detailed before. @Myles – thanks, that's kind of you. I'm glad the detail in the bug report was useful. I just wanted to check in and see if there'd been any progress on this. We're a little nervous that this bug could still end up in a stable release of Safari – can we be reasonably confident that won't happen? I'd also be really curious to know if there's something specific to the font that we're using that's causing the problem to occur, as I've yet to see it happening on other sites. I can’t talk about future products or releases but I can say I plan to start fixing this bug this week. Forcing the newline character to have the same width as the space glyph in WidthIterator::applyCSSVisibilityRules() fixes this, but I don't understand why. I need to continue investigating. I think I see. There's a block at the bottom of RenderText::computePreferredLogicalWidths() which is only hit if wordLen == 0 and !isNewline (which is the case here) which measures the width of the one character at index i and adds it to currMaxWidth. In our situation, that's the leading newline character. Then, later, we subtract it out like this: "widths.max -= font.width(RenderBlock::constructTextRun(&space, 1, style));". This expects that the width of this initial character is equal to the width of a space. Oh, the same thing happens for the trailing newline using stripTrailingSpace(). This bug appears to occur: 1. If the font's newline character has a width that's different than the space character's width 2. If an element is shrink-wrapped 3. And the element starts or ends with a newline character That's a pretty common set of conditions. It's surprising we haven't seen this bug earlier. I'll try to fix this today. Oh, I guess there's another requirement to trigger this bug: We're not using IFC to lay out the text. So I think the old code was actually correct. If you make an element with some newlines in it, and then you make a duplicate element except with spaces instead of newlines, all the other browsers display these identically. I think it would probably be a mistake to expose the widths of the newline characters to the web, since the width of those characters is probably bogus in most fonts, since that value isn't actually observable anywhere. So I think this is a pretty straightforward fix, then. Created attachment 447441 [details] Depends on bug 234428 Created attachment 447442 [details]
Patch for EWS
After applying this patch, https://design-system.service.gov.uk/ looks right. Uh oh, test failures! Created attachment 447491 [details]
Patch
Comment on attachment 447491 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447491&action=review > LayoutTests/fast/text/newline-width-expected.html:8 > + white-space: pre-wrap; > + white-space: nowrap; pre-nowrap :) > LayoutTests/fast/text/newline-width-expected.html:16 > +div:before { > + content: ""; > + position: absolute; > +} why is before content required to trigger this behavior? A simple shrink-fit content is not sufficient? Comment on attachment 447491 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447491&action=review >> LayoutTests/fast/text/newline-width-expected.html:8 >> + white-space: nowrap; > > pre-nowrap :) whoops >> LayoutTests/fast/text/newline-width-expected.html:16 >> +} > > why is before content required to trigger this behavior? A simple shrink-fit content is not sufficient? Correct - a simple shrink-fit content is not sufficient. I didn't investigate that part; I assumed this was a way to opt out of IFC. (In reply to Myles C. Maxfield from comment #25) > Correct - a simple shrink-fit content is not sufficient. I didn't > investigate that part; I assumed this was a way to opt out of IFC. It looks like this might has changed since I reported the bug – from testing quickly in r137 the bug is no longer occurring in the simplified CodePen examples (https://codepen.io/36degrees/pen/abyjzNr) or on a small number of the components/pages that I listed in my initial bug report. Created attachment 448463 [details]
Patch
Comment on attachment 448463 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=448463&action=review > LayoutTests/ChangeLog:10 > + The div:before { position: absolute; } is necessary to trigger this bug; I assume it's necessary to > + opt-out of IFC. maybe use <!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextIntegrationEnabled=false ] --> Comment on attachment 448463 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=448463&action=review >> LayoutTests/ChangeLog:10 >> + opt-out of IFC. > > maybe use <!DOCTYPE html> <!-- webkit-test-runner [ LayoutFormattingContextIntegrationEnabled=false ] --> Oh, I didn't know about that. Good idea. Committed r287724 (245805@trunk): <https://commits.webkit.org/245805@trunk> |