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

[css-text-decor] Feature request - add a property text-decoration-length that modifies the length of the underline #4557

Closed
kush-agra opened this issue Dec 3, 2019 · 22 comments

Comments

@kush-agra
Copy link

How about adding a property to be able to modify the length values of the underline so that the actual underline can be longer or shorter than the length of the text

@fantasai
Copy link
Collaborator

fantasai commented Dec 3, 2019

Would probably call it text-decoration-trim and have it be an offset with respect to the current edge, since the author doesn't actually know the length of the word, if we were to add it...

My main concern atm is that we don't actually have a clear definition of where the underline starts and stops. Hard to offset from an unknown position, and I'm somewhat concerned authors will obsess over this setting in ways that aren't interoperable across browsers or OSes. Otherwise, seems pretty reasonable to add.

@fantasai
Copy link
Collaborator

fantasai commented Jan 1, 2020

More fun questions: How does this interact with skipping spaces or margins or other things like that? How does it interact with line breaks?

@fantasai
Copy link
Collaborator

#4517 seems to be the same request.

@SebastianZ
Copy link
Contributor

SebastianZ commented Mar 14, 2020

I stumbled over a use case for this today. The links under "Aufgaben und Dienstleistungen" at https://www.landkreis-regensburg.de/buergerservice/bauen/bauamt/ have a hover effect that lets the underline "grow" from left to right.

This is achieved by using a ::before pseudo-element instead of text-decoration: underline;, which is absolutely positioned and has an initial width of 0 and gets a width of 100% on hover.

In order to make this possible with a text-decoration-trim property, it would need to be able to take two values for the start and end edge of the line, allow percentages (referring to the decorating box's width), and be animatable.
Then this effect could be created by applying text-decoration-trim: 0 100%; and on hover text-decoration-trim: 0 0;.

Would probably call it text-decoration-trim and have it be an offset with respect to the current edge, since the author doesn't actually know the length of the word, if we were to add it...

With percentages author's wouldn't need to know the length of the word, though trimming the decoration is the more flexible solution, in my opinion.

My main concern atm is that we don't actually have a clear definition of where the underline starts and stops. Hard to offset from an unknown position, and I'm somewhat concerned authors will obsess over this setting in ways that aren't interoperable across browsers or OSes. Otherwise, seems pretty reasonable to add.

If user agents don't agree on where the decorations start and end, then it won't be possible to get pixel perfect results, though I assume in this case it doesn't have to be. It just means "start/end the decoration <length-percentage> from where it would normally start/end".

More fun questions: How does this interact with skipping spaces or margins or other things like that? How does it interact with line breaks?

I'd say spaces and margins would be skipped like now for consistency and to make animations possible without any flickering.
As mentioned above, I think the property should work on the decorating box.

Sebastian

@aress31
Copy link

aress31 commented Sep 10, 2021

What is the status of this ticket?

This feature would be amazing and simplify CSS code a lot, right now the only way to achieve this is via an overkill ::before or ::after giving an easy way to trim/set the length of an underline should be a must and is long overdue!

@fantasai
Copy link
Collaborator

fantasai commented May 4, 2022

Initial proposal based on discussion above:

text-decoration-trim: <length-percentage>{1,2}
  • Specifies a shortening of the line decoration at the start/end of the decorating element.
  • On block containers, applies to both sides of each line. Percentages refer to the width of the containing block.
  • On inline elements, applies only to the start edge of the first inline box fragment and the end edge of the last inline box fragment. Percentage refer to the total length of the untrimmed line decoration. If the trimmed amount is more than the size of the relevant fragment, any excess trim is passed through to the next fragment.
  • Negative values are allowed, and extend the line decoration.
  • Skips are applied after trimming.

This property would replace text-decoration-skip-inset.

Open issues:

  • Have inlines also apply this per-fragment instead of per-element?
  • Call it text-decoration-trim or text-decoration-inset?
  • If percentages are used to represent the length of the line, how do we represent its thickness?

@SebastianZ
Copy link
Contributor

On block containers, applies to both sides of each line. Percentages refer to the width of the containing block.

Referring to the width of the containing block seems wrong to me as the decorations don't extend to that width. So decorations and their trimming would be disconnected.
I'd say, percentages should rather refer to the width of each fragment of the decoration box. By that, each line's decoration would be trimmed by the same percentage.

Alternatively, percentages could refer to the total length of the untrimmed line decoration of the in-flow inline-level children. That means, the percentage would affect the total length of the line across the fragments. So, basically what you've defined for inline elements.
Though it's probably good to specify different behavior for both, so authors can choose between two stylistic behaviors.

  • Have inlines also apply this per-fragment instead of per-element?

I'd say no. See my last sentence for the reasoning.

  • Call it text-decoration-trim or text-decoration-inset?

Both names seem valid to me for positive values. Though for negative values (actually extending the decorations) they both miss the point.

  • If percentages are used to represent the length of the line, how do we represent its thickness?

Do you mean how to refer to the thickness of the line when trimming it? If so, what are the use cases for that?

Sebastian

@fantasai
Copy link
Collaborator

@aress31 It's on the backlog of things for the CSSWG to discuss. Once that happens (should be within a month or so), if it's accepted as a proposal, we'll work it into the spec, address any open issues, and then it's a question of whether implementers are interested in implementing it. If you have some compelling examples showing off the effects you want, please post them here, that'll help implementers be interested. :) And also help make sure we're getting the design right and accommodating the important use cases.

@faceless2
Copy link

  • There's always been a demand for the ability to trim borders as well[1]. I'm for this proposal but it would be good to consider that this might come up at some point and to try and use terminology that could be applied consistently to borders too. If SO votes are anything to go by, trimming borders is more popular than trimming underlines[2]. So for that reason I like text-decoration-trim over text-decoration-inset, because border-trim is less confusing than border-inset

  • border-image-width uses raw numbers to refer to a proportion of the border-width[3]. I know Tab will hate this suggestion, but doing the same would at least be consistent (again, particularly so if this concept is ever applied to borders)

[1] https://stackoverflow.com/questions/4131490/any-way-to-limit-border-length.
[2] https://stackoverflow.com/questions/46219335/underline-exactly-50-of-my-text
[3] https://drafts.csswg.org/css-backgrounds/#border-image-width

@SebastianZ
Copy link
Contributor

For trimming and clipping borders, CSS Backgrounds 4 currently already defines two properties border-limit and border-clip.

So just throwing in text-decoration-limit or text-decoration-clip as alternatives.

And I just want to point out again that there are also use cases for extending the decorations, which probably doesn't apply to borders. And with that in mind, "limit" might be the best fit, but I don't have a strong opinion for any of those names.

Though regarding border trimming, I'd claim that in many use cases people actually want to style the gaps in between elements and trim those. And they only use borders due to the lack of alternatives. Discussions about that are happening in #2748, #5080 and #6748.

Sebastian

@jfkthame
Copy link
Contributor

jfkthame commented Jul 6, 2022

I'd say, percentages should rather refer to the width of each fragment of the decoration box. By that, each line's decoration would be trimmed by the same percentage.

Given a decorated <span> that's split across a line break, with a short fragment on one line and a longer one on the other -- and perhaps the widths changing as the content is edited -- this seems like it'd be a bit odd. Would we really want the adjustments to vary per fragment depending how line breaks happen to fall?

What about cases where the width of the box gets modified during layout by things like justification and tab-alignment -- would percentage-based decoration adjustments be affected, or should they be based on an intrinsic width prior to such adjustments?

@dbaron
Copy link
Member

dbaron commented Jul 6, 2022

Should the behavior at breaks be controlled by box-decoration-break? That is, with box-decoration-break: clone you would end up with the length modification at both ends of every fragment, whereas with box-decoration-break: slice you would end up with the length modification only at the start of the first fragment and the end of the last fragment.

@litherum
Copy link
Contributor

litherum commented Jul 6, 2022

Referring to the width of the containing block seems wrong to me as the decorations don't extend to that width. So decorations and their trimming would be disconnected.
I'd say, percentages should rather refer to the width of each fragment of the decoration box. By that, each line's decoration would be trimmed by the same percentage.

I think this is philosophically right, though there be dragons when you start talking about fragments of a line. E.g. consider that bidi runs are considered different fragments - do you really want the insets to apply separately to each bidi run even if the runs abut?

To be clear, I'm agreeing that the containing block is a worse solution than line fragments. But we may want to try to do a little better than line fragments too.

@litherum
Copy link
Contributor

litherum commented Jul 6, 2022

I'm also not sure about the <length> part of <length-percentage>. Authors don't know how wide their text is going to when it finally gets rendered (because they don't know things like which font will be used, whether the user has boosted text sizes, etc.), so it seems like there is no <length> value they could use that would be right.

@litherum
Copy link
Contributor

litherum commented Jul 6, 2022

I guess we also need to determine if this trim/inset/thingy will apply to both sides, or if we want it to take 2 values, one for the start side and one for the end side.

@SebastianZ
Copy link
Contributor

@jfkthame wrote:

I'd say, percentages should rather refer to the width of each fragment of the decoration box. By that, each line's decoration would be trimmed by the same percentage.

Given a decorated <span> that's split across a line break, with a short fragment on one line and a longer one on the other -- and perhaps the widths changing as the content is edited -- this seems like it'd be a bit odd. Would we really want the adjustments to vary per fragment depending how line breaks happen to fall?

That use case calls for the second option I gave.

The use case I had in mind for the first option, though, was a decorated headline split across multiple lines. In that case, it is very plausible to split the decoration between the fragments, especially when you want to work with transitions.

What about cases where the width of the box gets modified during layout by things like justification and tab-alignment -- would percentage-based decoration adjustments be affected, or should they be based on an intrinsic width prior to such adjustments?

I'd definitely say that such adjustments should be taken into account when calculating with percentages.

@dbaron wrote:

Should the behavior at breaks be controlled by box-decoration-break? That is, with box-decoration-break: clone you would end up with the length modification at both ends of every fragment, whereas with box-decoration-break: slice you would end up with the length modification only at the start of the first fragment and the end of the last fragment.

I like the idea of re-using that property to cover those to use cases. But, as @litherum wrote, there might be some downsides to it we should definitely discuss. And bidi text fragments should clearly be handled the same as non-bidi fragments, in this case.

@litherum wrote:

I'm also not sure about the <length> part of <length-percentage>. Authors don't know how wide their text is going to when it finally gets rendered (because they don't know things like which font will be used, whether the user has boosted text sizes, etc.), so it seems like there is no <length> value they could use that would be right.

Take my use case with the headline from above. For stylistic reasons it's reasonable to clip the decoration at a fixed size at each fragment. Of course, this would cause very short fragments to not have a decoration at all.
For such cases, we might want to introduce a minimal decoration width. Though that probably goes beyond the initial use case and could be discussed separately.

Sebastian

@jfkthame
Copy link
Contributor

jfkthame commented Jul 6, 2022

@litherum wrote:

I'm also not sure about the <length> part of <length-percentage>. Authors don't know how wide their text is going to when it finally gets rendered (because they don't know things like which font will be used, whether the user has boosted text sizes, etc.), so it seems like there is no <length> value they could use that would be right.

A <length> value in font-relative units (probably em, though others like ch or ic-width could be used) is perhaps the most likely to be useful/robust here.

I'm having a harder time picturing a lot of use cases where a percentage seems better than a (potentially font-relative) length. I do see the example @SebastianZ mentioned in #4557 (comment) where an "underline" animates from 0 to 100% width, but this seems like a very niche case, and I'm not entirely convinced it justifies added complexity within the web platform just to make this effect more convenient.

@fantasai
Copy link
Collaborator

fantasai commented Jul 7, 2022

@litherum One of the use cases for the feature this would be replacing is that in Chinese, there needs to be a visible gap between adjacent elements' individual underlines. If you add a slight trim, you can guarantee that effect.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-text-decor] Feature request - add a property text-decoration-length that modifies the length of the underline, and agreed to the following:

  • RESOLVED: Remove text-decoration-skip-inset, add `text-decoration-trim: <length> <length>?`, follow-up for improvements and issues
The full IRC log of that discussion <emilio> topic: [css-text-decor] Feature request - add a property text-decoration-length that modifies the length of the underline
<emilio> github: https://github.com//issues/4557
<emilio> fantasai: there's been a variety of requests for controlling the length of underlines
<fantasai> https://github.com//issues/4517
<emilio> ... we have some spec text to ensure that underlines break between words
<emilio> ... but we've been asked to provide more control
<emilio> ... suggestion is to define a new `text-decoration-trim` property
<fantasai> https://github.com//issues/4557#issuecomment-1117735704
<emilio> ... which would take a `<length-percentage>`
<emilio> ... and shortens the underline by the given amount
<emilio> ... there's the question of what's the percentage relative to
<emilio> ... so we could start with `<length>`
<emilio> ... on block containers we could apply it to both sides of the block
<emilio> ... on inlines it should follow the behavior of box-decoration-break
<emilio> ... negative values are allowed and would extend the text-decoration
<emilio> ... percentages were suggested to be relative to the containing-block
<emilio> ... there's some effect animating where that'd be useful for
<fantasai> https://www.w3.org/TR/css-text-decor-4/#text-decoration-skip-inset-property
<emilio> ... if we want to discuss percentages we can do that now but I'd like to add this to the spec and remove `text-decoration-skip-inset`
<emilio> ... as described above wrt inlines / blocks
<emilio> astearns: is text-decoration-skip-inset implemented anywhere?
<emilio> fantasai: I don't think so
<emilio> astearns: is trim the best word when negative lengths can be an extension?
<tantek> just like indent negative means outdent?
<fantasai> yep
<emilio> fantasai: I think so since negative trim is to extend the same way as negative extend is trim, I think use case is mostly trimming
<emilio> florian: the property that would be dropped had an auto value
<emilio> ... should this have the same value?
<emilio> ... if you want the browser to trim by the right amount
<emilio> ... so we'd be losing this but we could reintroduce this if wanted
<emilio> fantasai: yes
<emilio> astearns: fantasai, would this go into your initial write-up? or should we decide later?
<emilio> fantasai: I don't think an auto value is particularly useful if you can specify lengths
<tantek> +1 fantasai, worth documenting an actual use-case of for 'auto', like what problem is it solving?
<fantasai> it's solving the problem documented in https://www.w3.org/TR/css-text-decor-4/#text-decoration-skip-inset-property
<emilio> florian: in CJK when you have a piece of content and they might be next to each other, and without skipping you might not notice that they're different words
<emilio> ... you might want to say "browser, just do something"
<faceless> Easy enough to define "auto" as "the width of the underline" perhaps?
<emilio> ... you could do "3px" or something, but then why that?
<emilio> fantasai: I think the width of the underline was my initial thought
<emilio> ... though might not be useful if the underline is very big? So might be more like `min(0.1em, underline-width)` or something
<emilio> florian: do we want browser guidance here?
<emilio> fantasai: I think we want to do that so people know what to implement
<emilio> florian: [missed]
<emilio> fantasai: one of the problems we have with percents is that we have percentages for word-spacing etc to reference the font-size of the element? Maybe we can do that
<astearns> s/[missed]/I have wanted this without having an opinion on a specific value/
<florian> s/[missed]/As one data point, I have authored CJK content where I've wanted this, without having a view as to how big it should be./
<emilio> fantasai: happy to start with `<length>` / `<length>|auto` / then add percentages
<emilio> ... probably worth starting with length and add things afterwards
<emilio> plinss: question, removing lengths from the end of the decoration, or also from the skipping between descenders and so
<emilio> fantasai: just end
<emilio> astearns: we discussed that and run into implementation difficulties
<emilio> plinss: ok, just wanted clarification, would be weird if it trimmed from both
<florian> s/do we want browser guidance here?/can we leave it as browser defined, or do browsers want guidance here?/
<jensimmons> `text-decoration-trim: <length>` for the resolution
<emilio> jfkthame: one thing I wondered is whether we want two values, one for start, one for end
<emilio> fantasai: makes sense
<emilio> jensimmons: separate for start/end could be declared all at once
<tantek> q+ to ask about interactions with text-overflow
<emilio> ... could see authors creating some kind of drop-shadow-like effects
<fantasai> -> illustration https://github.com//issues/4517
<emilio> ... specially when combined with underline offset/thickness
<dbaron> maybe also when combined with italic/oblique
<emilio> ... there's the question of what happens with inline-box breaking
<emilio> astearns: that's the part where it'd follow box-decoration-break
<astearns> ack tantek
<Zakim> tantek, you wanted to ask about interactions with text-overflow
<emilio> tantek: just wanted to add with potential interactions with text-overflow: ellipsis
<emilio> ... do you want this always, only when there's no text overflow, do you want to trim from the ellipsis start...?
<emilio> fantasai: can't even remember whether the ellipsis gets underlined or not atm
<emilio> astearns: if you're not using trimming at all, it seems this is a higher level question, you should get control for whether the underline applies to the end overflow
<emilio> plinss: my intuition would be that the end would be that the end would be where it'd be without text overflow
<emilio> fantasai: [missed], something about box-decoration-break
<emilio> plinss: I like separate start/end, provides more interesting animation possibilities
<fantasai> box-decoration-break defaults to slice, which would get the behavior plinss describes
<emilio> RESOLVED: Remove text-decoration-skip-inset, add `text-decoration-trim: <length> <length>?`, follow-up for improvements and issues
<emilio> florian: could I ask people familiar with in-design and similar software if they have auto values and how it works if so?
<emilio> astearns: don't recall
<emilio> astearns: will ask about in-design underlines
<emilio> fantasai: should I add the definitions with auto / percentages in the first draft?
<emilio> astearns: I think it'd be good to add at least a note
<emilio> florian: either that or put the value in with an issue on how to define it
<emilio> fantasai: if people are fine with me adding it in I'd just do that since it makes it easier to discuss

@astearns
Copy link
Member

astearns commented Jul 14, 2022

@frivoal asked about support for something like text-decoration-skip-inset:auto in InDesign. It does not have this feature. But it also does not really have the concept of “adjacent separate elements with exactly the same style” that the example in the old spec text relies on.

@SebastianZ
Copy link
Contributor

Unfortunately, I missed the call.

astearns: is trim the best word when negative lengths can be an extension?
just like indent negative means outdent?
yep

The alternatives weren't mentioned on the call. Let me know if I should file a new issue to discuss the name but for now I'll summarize the suggestions made so far here: We had "trim", "inset", "limit" and "clip".
As mentioned earlier, I'd actually go for "limit". All others sound to be limited to shortening the decoration.

... percentages were suggested to be relative to the containing-block

That was the initial suggestion by @fantasai. Though as I pointed out in an earlier comment, they should rather refer to the decorating box.

Sebastian

@fantasai
Copy link
Collaborator

OK, I've committed the edits for this, with the syntax text-decoration-trim: <length>{1,2} | auto.

I'm not opposed to percentages, but because there are complications with defining it (and likely complicates with implementing it), I think we should defer that to the next level.

I'm also open to dropping auto, but since we had text for it already under the text-decoration-skip-edges property, I moved it instead of deleting.

Closing out this issue, please file new ones for any further adjustments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants