Skip to content
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

Text overflow with ellipsis is weird and ugly by design #18761

Closed
marcglasberg opened this issue Jun 23, 2018 · 134 comments
Closed

Text overflow with ellipsis is weird and ugly by design #18761

marcglasberg opened this issue Jun 23, 2018 · 134 comments
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: typography Text rendering, possibly libtxt customer: alibaba customer: bytedance customer: chalk (g3) customer: crowd Affects or could affect many people, though not necessarily a specific customer. customer: dream (g3) customer: money (g3) dependency: skia Skia team may need to help us engine flutter/engine repository. See also e: labels. found in release: 1.22 Found to occur in 1.22 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P1 High-priority issues at the top of the work list r: fixed Issue is closed as already fixed in a newer version

Comments

@marcglasberg
Copy link

marcglasberg commented Jun 23, 2018

Latest update: #18761 (comment)


Internal: b/137284394

Here (#4478) Hixie commented:

"Ok the plan is that rather than truncating individual characters until it fit, we will truncate entire atomic positioned glyph sequences (e.g. whole ligatures or shaped words) until the ellipsis fits. That would have the advantage of being much more performant. It would have the disadvantage of truncating the entire word if the whole line was one ligature (e.g. if your line was the word "Zapfino" in the Zapfino font, and it overflowed at the "o", we would replace the whole thing with a "...", rather than just the "no".)"

Although the above comment talks about ligatures, it seems to me this is being ignored, and whole words are simply being removed.

Now suppose the text "Laboris nisi ut aliquip ex ea commodo" gets cut right before word "ex". Since the previous word fits, it may cut some letters of that last word to fit the ellipsis, resulting in:

"Laboris nisi ut aliqu..."

However, if the horizontal space is a litter smaller, than the letter "p" from "aliquip" won't fit, and it will cut the whole word, resulting in:

"Laboris nisi ut ... "

But that's not how overflow works for other platforms, and it makes no sense to remove whole words. The obvious result, if "p" doesn't fit should be, just as before:

"Laboris nisi ut aliqu..."

As things are now, we tend to see a lot of words cut in their last 1 or 2 chars, and a lot of words completely removed, leaving a lot of weird white space. That gets particularly nasty in one line texts like titles.

Please, don't create weird behaviors for things with time-honored traditions like ellipsizing. Stick to what everybody else does. If you want, let the devs choose between both behaviors: enum TestOverflow {clip, fade, ellipsisWords, ellipsisLetters}.

If Arabic and other eastern languages have problems with that (as per issue 4478), you can even do some autodetection for characters of those languages, by adding the enum TestOverflow.ellipsisAutodetect.

@sir-boformer
Copy link
Contributor

sir-boformer commented Jun 25, 2018

I agree with you, the current ellipsis often looks out of place, especially in languages like German with long words:

E-Mail an das Straßenverkehrsbundesamt schicken --> Email an das ...

@zoechi zoechi added the a: typography Text rendering, possibly libtxt label Jun 25, 2018
@HannoOttens
Copy link

This is an issue for me aswell.
I have some right-aligned text that frequently overflows, resulting in a large white gap between the ellepsis and the right side of screen. This looks very odd.

@josvos
Copy link

josvos commented Oct 4, 2018

+1 here... ellipsis on just word boundaries and leaving (much) space unused after the ellipsis is not the right way, IMHO, at least not for small texts (e.g. labels in buttons, etc.). Please change this, optionally by adding ellipisChars or so to let devs choose (not needed for me, but if the word boundary is needed too).

@ConProgramming
Copy link

Yeah I have an email in A Text widget and the entire email gets cut out

@zoechi zoechi added the framework flutter/packages/flutter repository. See also f: labels. label Dec 4, 2018
@zoechi zoechi added this to the Goals milestone Dec 4, 2018
@sir-boformer
Copy link
Contributor

You can try this as a workaround. Not sure if it also works with ellipsis.

      Text(
        email,
        maxLines: 1,
        overflow: TextOverflow.fade,
        softWrap: false,
      );

@JonasJW
Copy link

JonasJW commented Jan 9, 2019

@sir-boformer sadly TextOverflow.ellipsis doesn't work like this but that is the way it should work in my opinion. Just replace the letters which are fading with '...'.

@Hixie
Copy link
Contributor

Hixie commented May 1, 2019

cc @GaryQian

@lukepighetti
Copy link

lukepighetti commented Jul 10, 2019

TextOverflow.ellipsis should work on vertical overflow, cut off the last word(s) and replace with ...

edit: I found out later that if you set maxlines it overflows appropriately, but it would be nice if it sensed maxlines based on it's parent container

@1343
Copy link

1343 commented Jul 12, 2019

Some issue I am also facing, if some word is fitting it's replacing the complete word

Text(  
 'Sachin Ramesh Tendulkar ',
   softWrap: false,
   maxLines: 1,
   overflow: TextOverflow.ellipsis,
   style: new TextStyle(
     fontSize: 13.0,
     fontFamily: 'Roboto',
     color: new Color(0xFF212121),
     fontWeight: FontWeight.bold,
   ),
 )

If er is not wraping it's removing complete tendulkar word and putting ... final text Sachin ramesh ..

@chunhtai chunhtai self-assigned this Jul 22, 2019
@chunhtai
Copy link
Contributor

chunhtai commented Jul 23, 2019

I also saw some weird behavior with the maxLines and overflow.
it seems like maxLines is ignored the if the overflow is set.

it seems this is by design

@chunhtai
Copy link
Contributor

Current ellipsis is based on soft line break that automatically inserted in paragraph builder. When the word can't fit in to the line, it will get pushed to next line, and that cause it to truncate the whole word if part of it cannot fit. I will come up with a new overflow enum that will truncate the line differently.

@Moncader
Copy link

@chunhtai
Been a while since an update.
Any word on progress?

In languages where there are no spaces built in to the language like Japanese, this problem is extremely visible when you mix an alphanumeric sequence with a Japanese string of characters.
This is extremely common for business names, project names, or movie titles, which is exactly the kind of string you don't want to cut as much.

@chunhtai
Copy link
Contributor

@Moncader We had some discussions on this issue and came up with way to fix it. However, the fix will be on engine side code which will be migrated to skia library in one or two months. We are waiting for that to happen first.

@duzenko

This comment has been minimized.

@vanlooverenkoen
Copy link
Contributor

Any progress on this issue?

@chunhtai
Copy link
Contributor

chunhtai commented Nov 4, 2019

@jason-simmons Do you know what is the status of txt skia migration?

@sparcsaswat
Copy link

DropdownMenuItem(
value: value.r_value,
child: Text(
value.r_text,
overflow: TextOverflow.fade,
softWrap: true,
),
)

In my case it is not working

@thailocnexle
Copy link

It is not a solution. It's a workaround. Be very cautious with using it. It changes how characters are displayed. Differences are subtle, but overall, letters are a bit wider.

Yes, this workaround increases letter spacing so it is not suitable for us. I just found another workaround which I not see in this thread:

 text.replaceAll(' ', '\u{000A0}')

We started to use it and it seems that it "just works" for all our use cases. It just replaces all spaces in text with Unicode No-Break Space character.

Hope it may help someone :)

this workaround make some Arab character broken (الماس => ا ل م ا س). need fix by Flutter team.

@dev-mahmoud-elshenawy
Copy link

Use this extension

extension StringEllipsis on String {
  String tight() {
    return Characters(this)
        .replaceAll(Characters(' '), Characters('\u{000A0}'))
        .toString();
  }
}

then use it as the following

Row(
         children: [
                              Flexible(
                                child: Text(
                                 value.tight(),
                                  maxLines: 1,
                                  overflow: TextOverflow.ellipsis,
                                ),
                              ),
                         ],
 ),

Working fine with Arabic

@Lonyless
Copy link

Lonyless commented Jan 12, 2023

Will this get fixed?

@RaymondBakker
Copy link

Will this be fixed?

No, this won't get fixed.

@mack-at-pieces
Copy link

A viable and just as elegant solution is to simply use TextOverflow.fade instead @RaymondBakker @Lonyless. That is what we've done for our products and its been just fine.

@dawid-niedzwiecki
Copy link

Will this be fixed?

No, this won't get fixed.

why not

@Lonyless
Copy link

@mack-at-pieces thanks for the tip, but unfortunately it wont for for my use case.

@Hixie
Copy link
Contributor

Hixie commented Jan 25, 2023

Status update: Fixing this issue requires changes in Skia. We're working with the Skia team to get them an up to date list of issues people would like fixed, and this will be at the top of the list.

@feinstein
Copy link
Contributor

Great to know! Will this be a problem in Impeller as well or is it already working there?

@tvolkert
Copy link
Contributor

tvolkert commented Jan 26, 2023

Great question @feinstein. We still use Skia for text layout, so Impeller won't affect this.

@anthonymoretti
Copy link

Yes, this workaround increases letter spacing so it is not suitable for us. I just found another workaround which I not see in this thread:

 text.replaceAll(' ', '\u{000A0}')

We started to use it and it seems that it "just works" for all our use cases. It just replaces all spaces in text with Unicode No-Break Space character.

Hope it may help someone :)

@roman-petrov that's a good fix. If you make one more modification it also replaces hyphens with non-breaking hyphens:

'UFC 284 - Makhachev vs Volkanovski'
    .characters
    .replaceAll(Characters(' '), Characters('\u{00A0}'))
    .replaceAll(Characters('-'), Characters('\u{2011}'))
    .toString()

Without the second replaceAll the text looks like this:

"UFC 284 -..."

Instead of this:

"UFC 284 - Makhachev vs V..."

@fullflash
Copy link

my current workaround is to replace.

str.replaceAll('', '\u200B')

@anthonymoretti
Copy link

Hi @fullflash, if you do it that way just be wary of issues with letter spacing, emojis and hyphens.

@chunhtai chunhtai removed their assignment Mar 17, 2023
@luckjjh
Copy link

luckjjh commented Mar 29, 2023

Any status update for this issue?

@fullflash
Copy link

 .characters
    .replaceAll(Characters(' '), Characters('\u{00A0}'))
    .replaceAll(Characters('-'), Characters('\u{2011}'))
    .toString()

Yes but this solutions also results incorrect breaking chars like "u" letter in word "you" as you can see in the screenshot

image

@tvolkert
Copy link
Contributor

/cc @Rusino @jason-simmons @dnfield

The Skia team is about to start looking into this. Rough plan is something like:

  • Run the line breaking/word wrap algorithm as we currently do
  • If there is overflow beyond maxLines and ellipsizing is enabled, then ignore the last line break and shape the entire rest of the text as one line
  • Truncate clusters in the last line until the ellipsis fits

Also, from discussion:

In the following example, none of the "bbb" word is rendered. The goal is to instead render as much of the "bbb" word as will fit.

Or if you replace the string with "http://www.google.com", the current algorithm only renders the "http://" because that point is considered to be a soft line break.

import 'package:flutter/material.dart';

void main() {
  runApp(
    Center(
      child: SizedBox(
        width: 200,
        height: 100,
        child: Text(
          'aaaaa bbbbbbb',
          style: TextStyle(fontSize: 30.0, color: Colors.white, backgroundColor: Colors.blue),
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
          textDirection: TextDirection.ltr,
        ),
      ),
    ),
  );
}

pull bot pushed a commit to TheRakeshPurohit/skia that referenced this issue Apr 12, 2023
Flutter bugs:
flutter/flutter#18761
flutter/flutter#114949

Change-Id: Ic37554a13589bf169283df18050a2e32faf4794b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/668478
Commit-Queue: Julia Lavrova <jlavrova@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
@zanderso
Copy link
Member

Closing as presumed fixed by https://skia.googlesource.com/skia.git/+log/0d31aa1f49cb8cfd790c44d92a9a023839524865

@TahaTesser TahaTesser added the r: fixed Issue is closed as already fixed in a newer version label Apr 19, 2023
@MisterLight
Copy link

This fix was added in version 3.7.12? Looks like nothing changed

@POlczak-ITTouch
Copy link

POlczak-ITTouch commented Apr 21, 2023

@MisterLight The changelog for 3.7.12 doesn't mention any changes related to this problem. The fix must be a part of some upcoming release

@zanderso
Copy link
Member

This will not be backported to 3.7. I have requested a CP into the 3.10 beta here #125308.

@github-actions
Copy link

github-actions bot commented May 5, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: typography Text rendering, possibly libtxt customer: alibaba customer: bytedance customer: chalk (g3) customer: crowd Affects or could affect many people, though not necessarily a specific customer. customer: dream (g3) customer: money (g3) dependency: skia Skia team may need to help us engine flutter/engine repository. See also e: labels. found in release: 1.22 Found to occur in 1.22 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P1 High-priority issues at the top of the work list r: fixed Issue is closed as already fixed in a newer version
Projects
Mobile - text review
  
Engineer reviewed
Development

No branches or pull requests