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-inline-3] initial-letters changing used, not computed font-size #4988

Open
faceless2 opened this issue Apr 22, 2020 · 8 comments
Open
Labels
css-inline-3 Current Work

Comments

@faceless2
Copy link

faceless2 commented Apr 22, 2020

An element used for initial-letters will have its used font-size adjusted based on the algorithm specified in css-inline-3. However its computed font size remains unchanged.

This is a problem for any child of the "initial-letters" element that refers to the parent font size as part of a style property - for example, if a child sets font-size: 0.5em, it will be 50% of the font-size the parent would have been, had it not been an initial-letter.

<p style="font-size: 20px; line-height: 1">
 <span style="initial-letters:3">
  A
  <span style="font-size: 0.5em; baseline-shift: 0.5em">
   B
  </span>
 </span>
</p>

The letter "A" has a computed font-size of 60px. The letter "B" has a font-size and baseline-shift of 10px, instead of the 30px an author would expect. Anyone creating superscript text as part of an initial letter would encounter this issue.

This issue is migrated from item 6 in #4171. There was considerable discussion of this in the January 2020 F2F, which is listed in the minutes however no resolution was reached.

@faceless2 faceless2 added the css-inline-3 Current Work label Apr 22, 2020
@faceless2 faceless2 changed the title [css-inline-3] initial-letters changing used, not computed font-siize [css-inline-3] initial-letters changing used, not computed font-size Apr 22, 2020
@faceless2
Copy link
Author

Doing some testing with this, and it's not that simple.

While changing the computed font size would fix the font-size for any superscript text (for example), it would break example 6 in particular from the css-inline-spec:

p::first-letter {
  initial-letters: 3;
  color: red;
  width: 5em;
  text-align: right;
  margin-left: -5em;
}

p {
  margin-left: 5em;
}

Here, the user wants "-5em" to be computed against the specified font size.

@fantasai
Copy link
Collaborator

Based on the discussion, seems like we should continue to say that the computed font-size is unaffected, and take @emilio’s suggestion of maintaining a multiplier, which will affect the used font size and other effects that key off of the used font size (which is a class of things we'll henceforth need to be more clear about).

I think the only things that need to key off the used font size are going to be anything (other than actual <length> values) that keys off the font-size or a character size in the css-text, css-text-decor, and css-inline modules.

Scanning through, looks like that list should include:

  • baseline-shift percentage values if line-height is also a percentage (thus referencing the font-size but not via em units)
  • letter-spacing and word-spacing percentage values
  • tab-size number values
  • text-decoration-* percentage values
  • text-underline-offset percentage values

Some side effects:

  • Need to decouple line-height percentages from em units, as they'll behave differently here. (And should have been different from the start but that ship sailed a couple decades ago.)
  • If we need another concept of "used font size", e.g. if we introduce per-font multipliers against font-size to optically equalize glyphs across a fallback list, then we need to be careful not to conflate terminology with what we're doing here. That kind of effect should not be accounted for here.

@fantasai
Copy link
Collaborator

Slight complication: #2040
Seems that sometimes people want to style the punctuation at the same font size as the body text. Not sure how to make both cases possible.

@faceless2
Copy link
Author

Invent a "uem" unit for used font-size? Give it a special meaning in initial-letters only?

@fantasai
Copy link
Collaborator

@faceless2 If we could distinguish inherited font-size vs explicitly set font-size, maybe that would work? Like maybe:

  • initial-letter sets some inheritable font-size multiplier which is part of the computed value of font-size (which is now a tuple, a length and a multiplier, with the length as the basis of 1em)
  • When font-size inherits, or is set to a percentage, the multiplier inherits also.
  • When font-size is set to a <length>, the multiplier is reset to 1.

(To help with terminology, we can say the "computed font size" is 1em, but the "used font size" is 1em×multiplier.)

@faceless2
Copy link
Author

faceless2 commented Jun 17, 2020

I had to read that a few times but I think I see what you're aiming at. So you'd essentially redefine font-size, baseline-shift, text-underline-offset etc. to explicitly include the multiplier aspect of the font-size as part of their calculations, but most other properties (eg margin-left) would remain unchanged.

So based on some of the examples linked from #2040, if you wanted "1st as your initial-letter, with st super-scripted and keyed off the used font size, but the leading quote the same size as the paragraph size...

p {
   font-size: 16px;
}
.initial {
    initial-letter: 3 3;
    width: 5em;
    margin-left: -5em;
}
.initial .quote {
    font-size: 16px;
    vertical-align: text-top;
}
sup {
    baseline-shift: 0.4em;
    font-size: 0.5em;
}
<p>
 <span class="initial">
  <span class="quote">&lquo;</span>
  1<sup>st</sup>
 </span>
</p>

The units used in sup are multiplied by our new multiplier, because they're font-relative. But the units in .quote are not, because they're absolute. And the width and margin-left properties are unaffected by this multiplier.

Have I understood this correctly?

@fantasai
Copy link
Collaborator

Not quite. font-size: 0.5em would reset the multiplier to 1, because it's a <length> value. But font-size: 50% would maintain the multiplier. This avoids any need to be careful about font-relative lengths generally. :) Only situations where font-relativity is expressed in percentages (line-height, font-size, and various text-* properties) would end up relative to the used font size.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed initial-letter used vs computed font-size.

The full IRC log of that discussion <fantasai> Topic: initial-letter used vs computed font-size
<fantasai> github: https://github.com//issues/4988
<faceless2> Scribenick faceless2
<faceless2> fantasai in some cases where the initial letter has multiple characaters, some of the characters may want to be of different sizes - for instances punctuation or superscripts or similar
<faceless2> fantasai the problem is that we can't just say the descendents of the initial letter take the font size of the parent, so we need to have some kind of distinction to see whether the author wants to make the descendent an absolute size or have it scale to the initial letter
<faceless2> fantasais proposal is the the initial letter sets a font size multiplier, so the font size is now a tuple - the font size and a multiplier. When font size inherits it inherits the multiplier, when the font size is set to a length it's set to one, and when it's a percentage the multiplier is not reset
<faceless2> this ensures that the multiplier set on an initial letter is inherited by its descendants, so they will be scaled to match the parent element.
<faceless2> so the author can choose between specifying an explicit size or one that is linked to the initial letter size
<fantasai> summary of the proposal: https://github.com//issues/4988#issuecomment-644472219
<fantasai> properties affected by multiplier: https://github.com//issues/4988#issuecomment-634920474
<faceless2> dbaron it sounds good. what if they wanted to use a font-relative unit that isn't an em, but they can use a calc for this: calc (1.5ch/1em * 1em)
<myles> q+
<faceless2> this leads to another problem - the unit dimensionality analysis in calc. Does this prevent you from using the calc() function?
<florian> I think the minutes above should be calc (1.5ch/1em * 100%)
<heycam> q+
<faceless2> fantasai can we multiply percentages by percentages any other place?
<astearns> ack dbaron
<faceless2> tab so long as the percentage resolves to a number, yes.
<dbaron> s/prevent you from using the calc() function/prevent you from doing calc(200% * 200% / 1em)/
<astearns> ack myles
<astearns> q+
<faceless2> fantasai percentages generally multiple to a length, so multiplying by another percentage would give you length squared which is not valid
<faceless2> myles the solution seems to add a lot of complexity for what is ultimately a corner case. and I don't see different sizes being very common
<emilio> q+
<faceless2> so I'm worried about the cost-benefit analysis
<faceless2> fantasai so we have to transfer this information down somehow otherwise we can't do this.
<faceless2> myles the other option is not to solve this problem
<dbaron> I could suggest another option...
<astearns> ack heycam
<faceless2> fantasai this is relatively common when for example an initial quote is supposed to be a different size to the text
<faceless2> heycam it's possible we could solve this for quotes in a different way, rather than relying on the author to put markup on this.
<faceless2> fantasai there is an open issue to alow initial punctuation to be done differnetly
<fantasai> s/done differently/selected via pseudo-element/
<astearns> ack heycam
<faceless2> heycam it's a bit weird that now we can't do getComputedStyle on an element and set it back as the computed style on en alement as now we'd get something that behaves differently. I don't like that there's a hidden value as that's not partcicularlyl obvious to the author
<AmeliaBR> +1 for heycam's concern. Computed style should be round-trippable. Used style could still be used for em units.
<faceless2> astearns i think the common case where the open quote is meant to match the size of the body text - is it going to be possibel with this to make this work?
<faceless2> fantasai yes, with this proposal you'd set the size to 1em to match the paragraph size
<astearns> ack AmeliaBR
<astearns> ack astearns
<faceless2> florian we want the abiliity to match the size to the parent text, and we want intervening markup to not mess things up.
<faceless2> fantasai we make font siz depend on the font sizr and line height of the containing block, which is not a dependency that we want to put in the computed value of the font-size. Doing so would make the font size computation much more complicated.
<astearns> ack emilio
<faceless2> s/siz/size/
<fantasai> s/we make/that would make/
<faceless2> emilio i wanted to echo some of the concerns raised by myles, but also to point out font size already has some complexity - for instance font-size: medium has complexity, if you change to a font that has a different meaning of medium there are already calculations going on there
<faceless2> myles we do that too but it's just for monospace, but the only reason that's there is because the default monospace font had weird metrics. I don't think we should consider that as a precedent.
<florian> s/to not mess things up./to not mess things up. Affecting the computed rather than used value would solve the second. Are is the first one the reason we're not going that way?/
<faceless2> emilio I agree, I don't think we should add to the complexity
<astearns> ack dbaron
<faceless2> dbaron so another idea which may be less complex is to have a separate property that causes an element to be excluded from the font size adjustment that the initial letter changes. We could have a property that could be set to prevent elements and exclude them from the size adjustment
<faceless2> so eventually ou'd take the multiplier and give it its wn property
<faceless2> q+
<faceless2> florian there's no use for a multiplier of 1.7em is there?
<dbaron> s/1.7em/1.7/
<dbaron> florian: if you wanted that you could just use 1.7em
<florian> me astearns , you were still very faint
<faceless2> fantasai so if we had an on/off switch, how are we tracking the multiplier? the property has to be stored somewhere, as a multiplier, not a boolean value.
<astearns> ack faceless2
<fantasai> faceless2: This is per-property multipler, you have a couple cases with e.g. margin-left: 1em
<fantasai> faceless2: want that to be font size of the paragraph
<fantasai> faceless2: but want the actual font size to be matching the initial letter
<fantasai> florian: So that works with fantasai's proposal, because can use ems or not; but not with dbaron
<dbaron> (dbaron and fantasai both start to disagree)
<faceless2> the proposap with the multipilier is it does not affect the use of em units or any other font units, just percentages.
<fantasai> https://github.com//issues/4988#issuecomment-634920474
<faceless2> it only applies to particular properties which are related to the font, and only to percentages.
<faceless2> s/proposap/proposal
<faceless2> this isn't purely about the font size its about several other things that are keying off the used font size.
<faceless2> so you can't use this for margin left, for example, because it only takes em values. and em values are not affected by the multiplier
<faceless2> the things where it needs to be relative to the used font size are things that are being done to the text itself, and in that case we're already allowing for percentages because they need to be inherited as percentages. But margin doesn't have this because we have no use case for it
<faceless2> astearns is not hearing a concensus on this
<faceless2> florian is not necessarily is opposed but was asking questions to help understand it better
<faceless2> astearns the way to go forward here is to go forward on the issue with some examples. I'm hearing enough reservations that we shouldn't resolve.
<faceless2> fantasai we'll take it back to the issues.
<faceless2> s/issues/issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-inline-3 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants