-
Notifications
You must be signed in to change notification settings - Fork 707
[css-inline-3] Initial-letters layout can be improved #5015
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
Comments
@faceless2, (At a first reading) I do not fully follow your propsal, it is all a bit technical for me, and I am probably therefore being dense, but it seems to me you are considering only the dropped initial case. The raised initial and (partially) sunken initial cases are not meant to be top aligned, |
And if I want this?: |
And if your |
The baseline shift is always the line-height times |
OK, but how does that make it easier for me to write my webpage? |
Well, that's a fair question I suppose. Before you can write a webpage using My company has now built a full implementation of the spec as it is, although we're building for print, not websites. In my opinion, this part of css-inline is unnecessarily complex. I don't think it works properly for hanging baselines or top-aligned images. Alignment for replaced content is still a bit unanswered. The reference box for So, with respect, I didn't open this issue to help you write your webpage. I'm trying to test the spec to see how well it works - to improve it[1]. Implementers hate incomplete specs; tightly defining the behaviour means we can write testcases (we love testcases); and no-one wants to waste time implementing something that doesn't fulfil the user requirements. Once it's shown to be easy to implement and cover all needs, it will be added to browsers. And that will help you write your webpage. I fully appreciate that [1] Also, I also left the last F2F having promised @fantasai I'd try to clean up the previous issue and make a clearer demonstration that regular alignment would work. Results TBD... |
Understood. I am arguing from a user's point of view to try to ensure the eventual recommendation does end up fulfilling user requirements. I am all for tightening up on handwaving in the spec, and for specifying in a way that is easier to implement (without compromising ease of use, which is paramount). I have a style sheet with a FIXME from 2015 awaiting initial-letters. |
@faceless2 Thanks for the detailed writeup. :) I think you bring up some good observations here. I also think @zed-vector’s point, “how does that make it easier for me to write my webpage?” is important. The syntax of You point out that there aren't actually two alignment points, there's one, and a shift. That's a good observation, and I think you're right we can simplify the spec by describing things that way. But both alignment points are necessary because that's how we calculate the correct size for the initial letter. The author can't calculate that size, because they don't have access to the font metrics. You also point out the case of hanging baselines doesn't work quite as expected for non-integer size values less than the drop value. But under your model, raised caps (size values larger than the drop value) would not really work as expected either. And central baseline alignment also doesn't work as expected. One of our goals in designing this feature is to let the author declare at a high level what they want to happen: how many lines to drop, how big, with respect to the rest of the text, they want the initial letter to be. And make the UA do all the necessary calculations. As you point out, some of these calculations could use some fine-tuning. We could have the initial value of But fundamentally, I don't think the API is wrong: I think it is communicating between the UA and the author at exactly the right level. We just have to do better at handling the details, particularly for non-Western scripts. |
As #4171 is closed, I need to come back to the main point I was making there, and have been trying to get over for quite some time now, that the API is wrong in this respect: where the height of the initial letter is less than the height of the number of lines indented to make space for it, then the initial letter should be aligned at the top, not the bottom. |
@fantasai, may I suggest that 'key off of' is perhaps neither the clearest nor most elegant English phraseology, and I think I have recently seen you use it in a draft spec edit. I am not sure exactly what you mean to say, (and venture to suggest that maybe you aren't either) otherwise I could be more helpful with an alternative wording. Perhaps 'be dependent on' or 'be determined by'? But neither of those is really explicit either. |
Thanks for sticking through to the end! Your comments indicate I should have been clearer on a few things, so I'll touch on those and then stop banging on about this for a bit and let it percolate through.
Thank you again for taking the time to go through this. I think what's defined now does works for alphabetic baselines, but it could be clearer. Presuming the second argument to I don't think what's there now works for hanging baselines, and if I've convinced you of that then I look forward to being part of the discussion on how to improve it. We have a decent testbed now with both algorithms implemented, so can easily trial any ideas. |
@faceless2 Wrt
In your model, if I'm understanding correctly, |
One possibility for fixing the hanging baseline case, in line with the request in #5329 would be to use the top alignment point when size < sink (in all cases). But not when size > sink, which would give consistent results across writing systems. Thoughts? |
Currently "raise" is defined as setting an initial letter sink of "1", so yes - with no changes to that definition, that's exactly what would happen, and yes it would be weird. But if the model was going to change the definition of how "raise" was defined would necessarily need to change as well, and I figured we'd cross that bridge if we got there. Your "alignment-point switch" idea is quite clever. It seems to cover zed-vectors cases for latin, and mine for Hindi, at least with the fonts I tested with. I'll try and get it implemented over the next few days too see how well it works. I don't know if there are any cases where bottom-alignment would be wanted for latin where size < sink (i.e. the existing behaviour), but short of providing the author a switch to choose (i.e. with |
@faceless2 Fixes committed for #5329 Is there anything else in this issue you think we need to address, or should we close it? |
There were several aspects to this, most of them a subjective "things could be a bit simpler" and one technical issue which is certainly fixed in #5329 - we've discussed the other parts, you've considered them and I think that's good enough for me. Thanks, and closed. |
The
initial-letters
property is defined to take two values - the first controls the size of the initial letter, the second how much the initial letter is moved up or down: its shift. The shift is relative to an initial alignment set by byinitial-letters-align
.I want to demonstrate first that the shift value and the
initial-letters-align
property are unnecessary, as the same results can be achieved with the regularbaseline-shift
andalignment-baseline
properties. And second, with hanging baselines, the currentinitial-letters
spec will give incorrect results.As currently defined:
Initial letters are inline elements. Their font size is fixed and determinable before any layout takes place. They do not contribute to the line-height calculation.
The initial letter is aligned with reference to both "over" and "under" alignment points, which are specified by
initial-letters-align
.Initial-letters shift is not required
If you have a fixed font size and two alignment points, you're overconstrained. One of these properties must be derived or ignored. The spec states it's the "under" alignment point that matters; the "over" alignment is not part of the block-axis layout algorithm. The "under" alignment point is positioned against a hypothetical position:
You can restate that paragraph exactly as
As our initial-letter doesn't contribute to the line-height calculation, the shift required by
initial-letters: 3 3
in the images below could equally be achieved bybaseline-shift: -2lh
. The actual height of any lines after the first is irrelevant.Furthermore, we've just aligned the initial letter against the alphabetic baseline of the first line - in this example, where it would be aligned anyway, thanks to the default values of
alignment-baseline
anddominant-baseline
.Non-alphabetic baselines don't always work.
With
initial-letters-align: hanging
, our "under" alignment point is still the alphabetic baseline of a hypothetical third line (remember the "over" point is unused). How does that work withinitial-letters: 3 3
?It works very well. Note we can still simply position against the alphabetic baseline of the first line then shift down by
2lh
.But, if we change the initial-letter to
initial-letters: 2.7 3
things don't look so good.Note the hanging baseline of the initial letter no longer matches the rest of the paragraph. How do we fix this? We can't. The "under" alignment point is what matters, and it's an integer value. The bottom of the initial letter must align with the bottom of the "ABC"
(note: the limitations of integer values for the shift was also raised by @zed-vector in #4171 (comment); it's not specific to hanging baselines - if you want top-alignment, you have to use an integer multiplier for size)
The solution here is to forget about

initial-letters-align
completely. Just setdominant-baseline:hanging
on the paragraph, then align our initial letter as a regular inline. Exactly as we could have done for the alphabetic baseline examples above:Vertical alignment of inline boxes on a line is a very well understood algorithm. Once you redefine
initial-letters
block-axis alignment to use the same algorithm, it becomes simpler to specify, implement and test. And you can redefine it this way, easily, once you drop the pretence that there are two alignment points.Here's a quick comparison of the two approaches for aligning initial-letters to their linebox.
Special Initial-letters-align algorithm
initial-letters-align
property, of which the "under" alignment points are either alphabetic or ideographic. Proposed user-agent defaults are recommended based on language.initial-letters-align: border-box
.initial-letters
size is an integer.Regular inline alignment
alignment-baseline
property, which is also the case for the rest of the paragraph. The default, "baseline", does the right thing if dominant baseline is set.dominant baseline
of the paragraph. Anyone wanting hanging, ideographic or other baselines would need to set this, as there is no user-agent default based on language.alignment-baseline: top
oralignment-baseline: bottom
Enough already, skip to the end
Here's my suggestion:
Either get rid of the second value of the "initial-letters" property, or make it a shorthand to set
baseline-shift
to "(1 - n)lh" - so1 = 0lh
,2 = -1lh
,3 = -2lh
, and the newly valid0 = 1lh
Get rid of
initial-letters-align
.Change the block axis positioning algorithm to something like:
There's less magic about initial letters than first appears. They're positioned like a regular inline, and content wraps around them like a float.
Finally, to verify I'm not imagining any of this, we've implemented both the currently specified algorithm, and the algorithm proposed in this issue. There is currently a beta of our layout engine available at https://bfo.com/publisher/?https://bfo.com/publisher/tests/213-initial-letters.xht, with comments inline showing how to try them out.
(Migrated from point three of #4171)
The text was updated successfully, but these errors were encountered: