Open hibachrach opened 5 years ago
Thank you for picking up my proposal, Harrison!
For reference, my proposal actually included two ideas. The first one was to allow cropping in the middle of the element's content and the second, related one to preserve some part of the contents on smaller element widths.
To avoid discussing two features at the same time, let's focus solely on middle-cropping here.
My proposal back then was to reuse text-overflow
for this purpose and simply add a third value to it specifying the cropping in the center of the contents. @MatsPalmgren had another proposal in the related enhancement request for Gecko, which let you move the end ellipsis. Both proposals turned text-overflow
into a shorthand and introduced different longhands allowing to control the different partial values separately.
Issues with the proposals, which need to be solved:
clip
should not be allowed for it.Sebastian
Additional note: The proposal only covers inline content cropping. There might be cases, in which you'd want to do block-level middle-cropping. Though I guess that's rather related to line-clamp
.
Sebastian
There might be cases, in which you'd want to do block-level middle-cropping.
Would there? on single line ellipsis, doing it it the middle makes sense to me, but on multiline, it seems a lot less useful. Maybe I'm just short on imagination. Do you have examples of when you'd want that?
I would appreciate this feature as well. macOS Finder uses an inner ellipsis likely because the most variation and differentiation in a filename is at the beginning and end of the filename.
<div class="mete">
<span class="mete-start">When rendering this long sentence </span>
<span class="mete-end">you will often see a middle ellipsis!!!</span>
</div>
.mete {
display: flex;
align-items: baseline;
justify-content: center;
height: 1.5em;
line-height: 1.5em;
}
.mete-start, .mete-end {
overflow: hidden;
height: inherit;
flex: 0 1 auto;
}
.mete-start {
word-break: break-all;
}
.mete-end {
white-space: nowrap;
direction: rtl;
text-overflow: ellipsis;
text-overflow: ' ...';
}
.mete-end::after {
content: '\200E';
}
Here's the utility I use to solve this gap in the spec. But it does have the caveats of not working in webkit, misusing direction
, and being tricky to semantically style (em
/strong
) text across the center boundary, but it is selectable and mostly accessible. :/
There might be cases, in which you'd want to do block-level middle-cropping.
Would there? on single line ellipsis, doing it it the middle makes sense to me, but on multiline, it seems a lot less useful. Maybe I'm just short on imagination. Do you have examples of when you'd want that?
Well, the cases are not as strong as the single-line cases, I guess. Though the principle stays the same, i.e. cases, in which you care more about the ending than the middle of the contents.
One use case could be the Inspector panel within browser DevTools, which shows the text contents of the elements. When they span over many lines, it gets quickly hard to skim over the HTML structure. Those could limit the contents to a specific number of lines but crop them in the middle of the contents, so it's easy to skim over them.
Example:
Could be shrinked to someting like in this mockup:
Sebastian
Giving the issues stated earlier some more thought, I came up with another approach than outlined in my first suggestion.
- Normally, you will only want to crop either at the beginning and/or end or in the middle, but not both.
We might introduce a text-overflow-position
longhand to cover that.
- For middle-cropping you will only want to have ellipsizing but not clipping, so
clip
should not be allowed for it.
Some possible options to handle this:
auto
value and make it the initial value. For start and end positioning of the overflow handling, the used value would then be clip
, for middle positioning it would be ellipsis
. (That requires checking web compatibility.)clip
also apply to middle positioning. (Though clipping the inline content in the middle probably doesn't have any use cases.)clip
for middle positioning as ellipsis
. (Might be unexpected.)clip
for middle positioning as if end positioning was applied. I.e. clip the contents at the edge where they overflow the element.
- Handling of inline contents other than text.
This would work very similar to the current definition. I.e. characters and atomic inline-level elements would be removed until the ellipsis fits.
With an auto
value as suggested above, the syntaxes might then look like this:
text-overflow
= <'text-overflow-handling'> || <'text-overflow-position'>
text-overflow-handling
= auto | [ clip | ellipsis | <string> | fade | <fade()> ]{1,2}
text-overflow-position
= [ start || end ] | middle
With names to be bikeshedded, as always. And only the first handling value would be applied if middle positioning is chosen.
The simplest middle-cropping could then be achieved via text-overflow: middle
. Some advanced examples would be text-overflow: middle fade(3ch)
and text-overflow: start end ellipsis
.
Doing so, we'd have to define what to do in cases like text-overflow: end start ellipsis fade
.
Sebastian
The initial suggestions celebrated 10 years anniversery yesterday. 😄 Maybe we can discuss the latest suggestion while we're at the F2F.
Sebastian
Random comment: for strings consisting of certain types of formatted text (e.g. URLs) it might make sense for the UA to choose an ellipsis position that's a bit more intelligent than positional from a layout perspective.
One question to be considered -- I'm sure it has been discussed previously, but don't have links on hand -- is how middle-cropping behaves in the case of mixed-direction (bidi) content. Does the line first get laid out without cropping, and then content is elided from the visual middle such that the edges are unchanged, or does content get elided from the logical middle of the line and the reduced content then laid out?
So, using uppercase letters to represent RTL characters, if we have a line where the full content is
abcdefghijklmZYXWVUTSRQPON
we have two possible results:
(1) "visual middle" ellipsis would give something like
abcdef…SRQPON
(2) "logical middle" ellipsis, on the other hand, would give us
abcdef…ZYXWVU
I tend to think (2) is the better result in most situations, given that the point of middle-ellipsis is to keep the beginning and end of the content visible, but this might not always be the desired result?
Implementation-wise, there may be some tricky cases here.
Bidi behavior wasn't brought up so far, as far as I can tell. So, thanks for that!
My gut feeling is also to go with option 2, though I have to admit I don't really have much experience regarding bidi text. Also, the case you've shown is the most simple one. What if you have a right-to-left part in an otherwise left-to-right sentence and the cropping happens to show a part of both?
I.e.
abcdefghijklmZYXWVUTSRopq
I'd say the result should be
abcdef…ZYXopq
Though I'm not sure about that.
Sebastian
Let's use actual words instead of lined-up letters. If we go from this example, and need to delete 5 characters:
he greeted them: ?UOY ERA WOH ,HI
Visual middle gives:
he greeted the…OY ERA WOH ,HI
Logical middle gives:
he greeted the…?UOY ERA WOH ,
Logical middle looks unexpected and confusing to me.
Also, with visual middle, there's no complication if the font isn't monospaced, or if there are multiple fonts or font sizes on the line, whether there's kerning, whether there is some white space collapsing, some ruby… It's a paint based operation, and so the middle can just be geometrically halfway between the start and end edges. Or we could shift it around a bit if we wanted to without any particular complication. In the case of logical middle, it gets a lot messier. Counting code points is easy, but isn't a particularly good proxy for what feels like the middle to a reader, and doing other things seems an unpleasant mix of complicated and arbitrary.
Thinking in terms of use cases, this particular feature request seems to be driven by ellipsis in the middle of file names, URLs, serial numbers, and the like.
C:\Photos\صورة.jpg
Here, the bits that are most important to preserve as C:\
and .jpg
. For the rest, I'd argue it doesn't really matter all that much what gets chopped off, and to the extend that it does matter, that we're unlikely to find consistent rules that are ideal in all scenarios. For example, here, whether you're better off chopping some of the file name, or some of the directory name, or a bit of both, most likely doesn't depend on how short or long the file name and directory names are, and more likely depends on what the user is trying to do learn from that path.
All in all, unlike block-ellipsis
, where processing things in logical order does seem important to me, for text-overflow: middle ellipsis
, I'd argue for visual middle.
I suspect that for mixed-direction content, any approach will sometimes give somewhat odd results, but I'm still inclined to think that "logical middle-cropping" is better than visual, if it can be implemented reasonably.
In particular, the case of URLs, file paths, etc., where components of the path are right-to-left seems to me to call for logical cropping. In your extreme example with
C:\Photos\صورة.jpg
it perhaps wouldn't matter much; but in a longer example with multiple RTL directory names, visual middle-cropping is liable to lose the actual filename (leaving the top-level directory), whereas it would probably be more useful to keep the filename and lose the top-level dir (as happens with a purely LTR path).
See https://codepen.io/jfkthame/pen/ExGqBYd for an illustration, where IMO the logical version is preferable -- although any result for mixed-direction paths can be confusing, I think.
As for how to implement logical middle-ellipsis.... I'm not sure, exactly, but I think it's at least worth giving it some more thought. Things like counting codepoints are surely not the answer; it has to be based on measurement of (shaped) text.
Bidi content is definitely hard to handle and may not always provide the best results. Though UAs should try to do their best to output the contents as expected.
Thinking in terms of use cases, this particular feature request seems to be driven by ellipsis in the middle of file names, URLs, serial numbers, and the like.
Yes, file paths and URLs were my main use cases. Therefore, I welcome @fantasai's comment about letting UAs be smart about where to crop the contents.
As for how to implement logical middle-ellipsis.... I'm not sure, exactly, but I think it's at least worth giving it some more thought. Things like counting codepoints are surely not the answer; it has to be based on measurement of (shaped) text.
Yes, measurement-based positioning seems reasonable as we need to keep non-textual contents in mind. And as @frivoal pointed out earlier, textual contents may also differ in different aspects.
Though I think the spec. is already prepared for that by saying
For the ellipsis and string values, implementations must hide characters and atomic inline-level elements at the applicable edge(s) of the line as necessary to fit the ellipsis/string, and place the ellipsis/string immediately adjacent to the applicable edge(s) of the remaining inline content. The first character or atomic inline-level element on a line must be clipped rather than ellipsed.
So, inline contents are layed out and then characters and atomic inline-level elements are stripped off until the ellipsis/string fits. We just need to define that in more detail and specify what "applicable edges" are. Implementation-wise, this probably requires to define an algorithm. Trying to roughly outline one, I'd say:
Sebastian
But it has the caveats that it doesn't work in webkit
@jonjohnjohnson fwiw, this seems to work for me in Safari Version 17.0 (19616.1.27.211.1)
The CSS Working Group just discussed [css-overflow-4] Ellipsizing of text in middle of string
, and agreed to the following:
RESOLVED: Start work on middle ellipsis in css-overflow-4
For what it's worth, one thing I was going to add to the discussion regarding bidi is that my intuition about real bidi usecases (which are different from the testcases we write!) is that real bidi use cases generally have a dominant text direction and small pieces of text in other directions.
I think that might make me lean towards the idea that visual is fine for the middle like it is for the ends, but I'm also not really an expert on the use cases...
There might be cases, in which you'd want to do block-level middle-cropping.
Yes, the vue-clamp
component implements the ellipsis position, which takes values 'start' | 'middle' | 'end'
, this on github currently has close to 700 stars. cc @Justineo
Another case we have in Proton Drive: we want to keep the last characters to display the extension of a file (with long filename, for security reasons)
We did implement a solution by splitting the filename thanks to this component https://github.com/ProtonMail/WebClients/blob/main/packages/components/components/ellipsis/MiddleEllipsis.tsx but when we have a mix of RTL/LTR, it's a nightmare.
A native solution with an offset would be really helpful there :)
EDIT: some explanations of the issues => https://www.smashingmagazine.com/2022/12/deploying-css-logical-properties-on-web-apps/#mixing-rtl-and-ltr-content
Hello,
There are many cases in which the information at the beginning & end (but not middle) of a string of characters are important, especially in technical identifiers (e.g. URLs, file names, library call numbers, etc.). It would be wonderful if this was supported in CSS itself. Attempts to do with the current tools available are unattractive and complex at best.
Apologies if this is better addressed in the mailing list--the guidelines and other material online were unclear which is preferred in cases such as these.
I am following on from a previous inquiry led by Sebastian Zartner, to whom I owe thanks. His
www-style@w3.org
thread from 2013 ended without any conclusions or next steps. Note that I am not the author of the detailed proposal listed below, but merely a web developer interested in highlighting this proposal.