w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.51k stars 669 forks source link

[css-text-decor] Text underlines' positions cannot be fine-tuned #459

Closed litherum closed 7 years ago

litherum commented 8 years ago

Designers often want to control the thickness and position of underlines. Typographically, these underlines often are the thickness of certain particular strokes inside glyphs, which browsers / text libraries have no concept of. Therefore, information required for higher quality sizing / placement must come from somewhere else.

Naively, this additional information could come from the "post" table inside font files. However, because this information is often unused, many font files have garbage data in these fields. (As an aside, I committed a patch to WebKit to use these fields, but had to revert it 7 hours later because of the low-quality data.)

Therefore, this information should come from page authors. There should be a new property: text-decoration-thickness: auto | <length> | file

The auto value is the default, and represents browsers' current behavior. The file keyword means to use the values from the primary font file itself (where "primary" means "the same font file which determines the horizontal and vertical text metrics for the element"). If a font file format is used which does not include these values, then file behaves like auto.

In addition, two new values should be added to text-underline-position, thereby making the syntax: text-underline-position: auto | [ under || [ left | right ] ] | <length> | file

With this syntax, it is impossible to specify both a <length> as well as under, which is on purpose. The <length> only applies to regular underlines, not to overlines, under-underlines, nor strikethroughs.

In addition, because of the semantic meaning of text decorations, browsers should be able to clamp these values to implementation-dependent sane ranges.

litherum commented 8 years ago

Perhaps percentages should be allowed, resolved against the font-size of the element.

Also, because font-family is inherited, text-decoration-thickness should be inherited too.

upsuper commented 8 years ago

text-underline-position is for the position of underline. As a side effect, it affects where overline is, but I don't see why making it impossible to specify both <length> and under makes any sense. Actually I don't see how putting thickness into text-underline-position makes any sense at all.

Text decoration line properties generally doesn't inherit, because they control the decoration line across an inline box as a while. I know WebKit and Blink mis-implemented those properties as inherited, but I believe that is undesired. Unless there is a good reason, I don't think text-decoration-thickness should be inherited (assuming we would agree to add it, which I have no strong opinion on).

litherum commented 8 years ago

I think you're misunderstanding this proposal. This proposal has two pieces (which keep position and thickness separate):

  1. Add a new property: text-decoration-thickness
  2. Add values <length> and file to the existing property text-underline-position

text-underline-position already exists and is inherited. In addition, the existing property does not affect overline (it isn't "text-decoration-position" but is instead "text-underline-position")

upsuper commented 8 years ago

Hmm, okay, yeah I probably misunderstood the proposal. So the <length> is about shifting the position of the underline, not controling thickness. That part probably makes sense, although I wonder where would the offset starts. Assuming the baseline? FWIW, text-underline-position should affect position of overline to ensure they are always on the opposite side (in case of left and right), but yeah, specifying offset shouldn't affect overline.

litherum commented 8 years ago

Yes, the offset should start at the baseline. Positive values should be "farther away from the text."

I'd like to amend the proposal to use a unitless number which would scale with font-size instead of <length>. It should be "A value of '1' represents 1px at font-size: 16px, and scales linearly with font-size." That way, when it's inherited, this value would react correctly to different fonts.

fantasai commented 8 years ago

Myles reminded me to comment here: text-underline-position should not be reused for this feature, because it's intended to inherit differently from stylistic considerations like color and line-style in order to align itself with language changes.

Might also be worth trawling www-style for past discussions on these, in case there are some good ideas. Certainly these requests have come up, but were deferred from L3.

kojiishi commented 8 years ago

+1 to add a new property for offset.

kojiishi commented 8 years ago

the offset should start at the baseline

and probably for CJK (or when text-underline-position: under|left|right), the offset should start at the edge of the em box. This tweet (sorry in Japanese but I hope the picture tells something) explains how to set the underline position to the bottom of em box in InDesign.

@r12a: now I wonder, since Latin and CJK want different point to start the offset from, if there were any other requirements in other writing systems?

Crissov commented 8 years ago

Instead of file, wouldn’t a new font-dependent unit, e.g. sw for ‘stroke width’, make more sense? It could also be useful with border-width for instance.

At least for serif (or broken/blackletter) faces, it may even make sense to introduce two units, one for the stem / base stroke (downstroke, \ in x) and another for the hair stroke (upstroke, / in x), i.e. bs and hs or ds and us. I assume most typefaces have an underline thickness around 1hs.

Seeing that ex is implemented as fixed 0.5em almost everywhere, a similar fallback value would be defined for the stroke unit(s) as well, maybe depending on the value of font-weight.

aaaxx commented 8 years ago

I really like this idea. If stroke width is possible to implement as a unit, I think it would also make for a much better way of selecting font weight in the new variable fonts, instead of the current numbers, which force you to take a stab in the dark.

Crissov commented 8 years ago

There was #487 for percentages in font-weight. Defining these as stroke-width divided by font-size (i.e. calc(1sw / 1em) or, possibly more useful, calc(1sw / 1ex)) would lead to different values than I’d expect (which would be a similar but formalized alternative to arbitrary 3-digit unit-less numbers), but could be reasonable.

stroke-width could also be a new font descriptor in @font-face, taking a mandatory (sw = bs) and an optional value (hsbs) as <length> | <percentage>.

aaaxx commented 8 years ago

Just to confirm I'm reading this right:

  1. You're thinking about declaring font-weight by setting the base stroke's width to some percentage of em or x-height?
  2. Abbreviations mean:
    • sw is stroke width
    • bs is base stroke (i.e. the thicker stroke)
    • hs is hair stroke (i.e. the thinnest stroke, obviously)
  3. The hypothetical stroke-width would be an alternative way of setting weight, by giving either base- or hair stroke a certain width? (Isn't base stroke here redundant if I understood point no. 1 correctly? Or do you mean leaving font-weight as currently specified and using stroke widths for manipulating weight just in this new descriptor?)
r12a commented 8 years ago

now I wonder, since Latin and CJK want different point to start the offset from, if there were any other requirements in other writing systems?

I'm not clear exactly how this works, but baselines are different not only for CJK fonts but also for indic fonts (at least nominally), which have a hanging baseline, ie. at the location of the horizontal bar in

अंतर्राष्ट्रीयकरण गतिविधि

So i'm not clear whether the starting point for the offset, if it was measured from the baseline, would need to be adjusted for each type of script in the document. If so, things would become particularly problematic where you have a combination of scripts with different baselines on a line. Not only would you need to markup up text so that each part gets its own correct offset, but you'd also have to figure out how to have a single underline at the same location under a mixed script phrase, eg.

अंतर्राष्ट्रीयकरण गतिविधि, W3C or 国際化活動 W3C

Hopefully i'm missing something and this won't be an issue?

Crissov commented 8 years ago

@aaaxx 1. and 2. correct, re 3.: It would be a way to explicitly set these units for specific fonts. Now I wonder whether we should have such a thing for ex (or proposed cap) – would need a separate issue: #731.

kojiishi commented 8 years ago

@r12a:

I'm not clear exactly how this works, but baselines are different not only for CJK fonts but also for indic fonts (at least nominally), which have a hanging baseline

Me neither, so this is a topic i18n needs to think about. Once we understand requirements for each languages, I think we can come up with how this should work, but we don't understand that yet.

I think we know:

Type Baseline Underline position
Latin Use the alphabetic baseline in CSS, or romn baseline in OpenType. Default to slightly below the baseline. When custom, specify the offset from the baseline.
CJK Use the central baseline, or ideo. Default to the bottom of em box, or left/right of em box in vertical. When custom, specify the offset from the edge of em box. Maybe CK is different from J, I don't know.
Indic Use the hanging baseline, or hang. ???
Any other types? ??? ???

and you're right that mixed case needs a separate consideration. I'm guessing we should align to the primary script, but it's the case for J, and how to determine the primary script is another question.

I discussed with @upsuper offline that CLREQ should have description about underline, great if we can understand underline requirements for other languages as well.

c933103 commented 8 years ago

When writing vertically, Chinese text usually put underline to the left of the text as per CNS (Taiwan) standard (de facto in other area as well) but then it seems Japanese usually put it to the right.

Crissov commented 8 years ago

@c933103 Do “underlines” in vertical text correlate by any chance with preferred direction of line progression, i.e. tb-lr ↓→ vs. tb-rl ↓←?

upsuper commented 8 years ago

No. Japanese and trandition Chinese both use vertical-rl, but they have different underline position.

r12a commented 8 years ago

@Crissov that's a distinction that may be relevant to Mongolian vs CJK. As @upsuper just said (while i was about to type it) CJK are all tb-rl.

Crissov commented 8 years ago

Thanks, that’s how I remembered it, just wanted to make sure.

c933103 commented 8 years ago

image Note that some software seems to have problem in handling underline with subscript/superscript in vertical position. And also note that in some situation if underline only apply to those superscripted/subscripted text then it might be oppose to the above example and would actually be desirable to let the line follow those subscripted/superscripted text.

r12a commented 7 years ago

i'm a little concerned that this issue is developing separate threads for line positioning and line thickness, and inclined to think that we should split out one or both into separate issues.

Crissov commented 7 years ago

@r12a We already have #239 for the thickness.

tiroj commented 7 years ago

As @litherum notes, the underline position and thickness values in a font's post table are liable to be junk data, since many font makers simply leave these as tool defaults. They are also font level settings that make no account for the possibility of multiple scripts and writing systems supported by a font that might require localised underline position and thickness.

Obviously, in this situation, it makes sense for CSS to come up with some reasonable fallback method to automate underlining, but I still think it would be preferable for the font developer to provide good and localised data. I've introduced this idea to the ad hoc OpenType working group, and will see what kind of traction I can get. Mostly likely implementation would be new fields in the BASE table, using existing OTL script (and maybe language system) tagging for localisation.

Having new data separate from the post table values should encourage font developers to provide better data, especially if font tools require them to make explicit decisions rather than providing default values. That is, this data should only be included in fonts if a developer has explicitly defined it; in the absence of this new data, CSS should fall back to automated underline position and thickness. Make sense?


PS. Everything I've written here regarding underline also applies to strikethrough.

litherum commented 7 years ago

I've renamed the issue to only discuss positioning here. We can discuss thickness in https://github.com/w3c/csswg-drafts/issues/239

litherum commented 7 years ago

There are a few distinct things here:

  1. Describing language conventions for how underlines look in existing media
  2. The possibility of speccing a fully-described underline placement algorithm
  3. The possibility of adding a single property which can fine-tune the underline's placement

Item 1 is not required for item 3, but item 1 is required for item 2.

Item 3 is more valuable in the presence if item 2, but is still valuable even without item 2. We have gotten many requests from web developers who just want to tweak the underline a little bit because of the specific typographic situation their page employs.

Performing items 1 and 2, while ultimately helpful, will take a long time (and many different people) to complete. Therefore, blocking item 3 on them seems unnecessary, since item 3 solves a real need and is fairly simple. In addition, if we spec item 3 now, it will still be meaningful even after completing items 1 and 2.

fantasai commented 7 years ago

I've drafted up a proposal in https://drafts.csswg.org/css-text-decor-4/#underline-offset

Didn't tackle the stroke-width unit issue. Please file a separate issue against css-values for that. :)

phistuck commented 7 years ago

What about letting the author decide whether the the user agent should use the underline (and similar) information from the font itself? Something like -

@font-face
{
 /* Standard font properties */
 src: url('font.woff');
 /* A new property, bikeshed later ;) */
 underline: from-source;
}

Web font factories should (or could) know whether this makes sense or not for a certain font and not specify it if they do not know. Remember that a lot of websites (and fonts) are using a single script/language/locale anyway, so the per-locale information is not necessarily relevant to them. This could make some big portion of the web enjoy accurate underlines (and similar).

This could be in addition or an alternative to underline-offset.

litherum commented 7 years ago

@phistuck It's valuable to let web authors opt-in to metrics in the font file, and a new value to the text-underline-offset property - not a descriptor in @font-face - is the most natural way to do that. However, the specific algorithm is a little nuanced because of font fallback. In particular, you don't want the underline to jump around just because a fallback font is chosen for a single character. Luckily, the text-decoration spec already has the concept of a "decorating box" so the metrics should be chosen from the primary font of the element from which the decorating box is created (where "primary font" means "the font which affects the element's ascent and descent metrics")

yisibl commented 7 years ago

text-underline-offset +1

fantasai commented 7 years ago

The CSSWG resolved to add text-underline-offset on January 12th: https://lists.w3.org/Archives/Public/www-style/2017Feb/0055.html You can see the text in the Editor's Draft here: https://drafts.csswg.org/css-text-decor-4/#underline-offset

If there are problems with specific details of how it's specced, please file new issues.

Thanks!