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-ruby-1] Propose to treat rtc with orthogonal writing-mode to be inter-character rather than using ruby-position #1773

Closed
upsuper opened this issue Sep 1, 2017 · 18 comments

Comments

@upsuper
Copy link
Member

upsuper commented Sep 1, 2017

Motivation

In current spec, inter-character ruby is handled via ruby-position: inter-character, which would make the writing mode of ruby annotation container (rtc) vertical.

As discussed before, there are some difficulties for this mechanism from some kind of circular dependencies between properties. Specifically, display property depends on writing-mode of the specific element and its parent for blockification, while this mechanism would make writing-mode depend on display and ruby-position. Although in this specific case, the circular dependency can be resolved if we defined the handling steps clearly, it seems to be a broken approach in general.

There is another difficulty that, writing-mode is a property needs to be locked at very early stage of style calculation, because font metrics depends on this property, and font metrics may be used in various properties (e.g. for ch, ex units), which means the fixup of this property need to be done before other properties get computed. This would add unnecessary complexity to style cascading, at least for Gecko (especially our new style engine, Stylo), because we generally do all the style fixup after cascading all properties.

Another issue is that, setting writing-mode on ruby annotation container is not enough, because there could be ruby annotation box which don't inherit from ruby annotation container. e.g. in a form like <ruby>我<rt>ㄨㄛˇ</rt>起<rt>ㄑㄧˇ</rt>來<rt>ㄌㄞˊ</rt>了<rt>˙ㄌㄜ</rt></ruby>. In this case, writing-mode would not be set properly.

Proposal

I propose that we use a different approach to implement inter-character: when the ruby annotation container has an orthogonal writing mode [wm1] to that of its base container [wm2], the annotation container is put at the wm2 inline-end of the base container, and layout in wm1 direction, so it looks like inter-character when it has only a single ruby annotation inside. Then we can remove inter-character value from ruby-position property.

It would require author to write something like

<style> rtc { writing-mode: vertical-rl; } </style>
<ruby><rtc>ㄨㄛˇ</rtc><rtc>ㄑㄧˇ</rtc><rtc>ㄌㄞˊ</rtc><rtc>˙ㄌㄜ</rtc></ruby>

This would avoid the difficulties for handling style fixup described above. There is a side benefit of this approach that, it would allow horizontal-in-vertical style inter-character ruby, although we don't see many usecases for that, it removes the special case that inter-character only takes effect in horizontal writing mode, and it only generates vertical-rl writing mode, so I think this approach looks more elegant in general.

Drawbacks

The using of <rtc> is unfortunate for this kind of solution. But if we want to have <rt> work as well in this case, we can specify that the anonymous ruby annotation container inherits from its ruby annotation box children somehow. Since anonymous boxes are created after style cascading, I think this should be easier to do than resolving the style dependency.

There would be another issue that in a browser which doesn't support treating orthogonal <rtc> as inter-character, it would render the annotation vertically on top. This may become a larger problem if we propagate style from <rt> back to anonymous ruby annotation container. Having ruby-position: inter-character forcing writing mode on rtc wouldn't have this problem.

Alternatives

Probably we can create an anonymous box inside ruby annotation box which would have the new writing-mode. With this, we would not need to worry about style computation anywhere else, because anonymous box cannot be styled by author style. But the problem is that we cannot have any element inherit from an anonymous box, that means element inside ruby annotation box would be in a weird situation in that case.

@upsuper upsuper added the css-ruby-1 Current Work label Sep 1, 2017
@upsuper
Copy link
Member Author

upsuper commented Sep 1, 2017

cc @kahsieh @kojiishi @fantasai

@upsuper
Copy link
Member Author

upsuper commented Sep 1, 2017

(FWIW, @kahsieh has an experimental impl with this proposed approach in Gecko, although it has not landed.)

@FremyCompany
Copy link
Contributor

FremyCompany commented Sep 5, 2017

Edge does not support the inter-character value for ruby-position, so this wouldn't be a breaking change for us. It seems weird that ruby-position:above + writing-mode:vertical does change the actual position not to be above, doesn't it? Though, it still makes sense if you think in the referential of the ruby itself actually.

@kojiishi
Copy link
Contributor

kojiishi commented Sep 6, 2017

@litherum I believe WebKit shipped inter-character support with prefix. Blink has -webkit-ruby-position but doesn't support inter-character.

/cc @bobbytung

@kahsieh
Copy link

kahsieh commented Sep 6, 2017

It appears that Safari already accepts the proposed syntax, although the result has slightly wider spacing without additional fiddling:

Using <ruby style="ruby-position: inter-character">:
image

Using <rtc style="writing-mode: vertical-rl">:
image

Edit: @upsuper points out that this is just because Safari doesn't recognize <rtc> and treats it as an unknown inline element. Perhaps this can serve as a fallback behavior.

@upsuper
Copy link
Member Author

upsuper commented Sep 6, 2017

@kahsieh's example actually reminds me another concern raised before for this proposed approach that, browsers which don't support treating rt with orthogonal writing-mode as inter-character would show something unreasonable (vertical ruby on top), which is undesired. ruby-position: inter-character inferring writing-mode would avoid this issue...

@kahsieh
Copy link

kahsieh commented Sep 7, 2017

Then, with this proposal, if we want to have the fallback behavior seen above (which is probably more desirable than displaying vertical ruby on top), we would have to stick with requiring <rtc> (and not having anonymous <rtc> inherit from <rt>), and engines other than Gecko would have to ship <rtc> and inter-character support simultaneously.

Edit: That is, in this approach, <rtc> behavior with an orthogonal writing mode would become well-defined, and inter-character ruby would become part of correct <rtc> behavior rather than being a separate feature.

@upsuper
Copy link
Member Author

upsuper commented Sep 7, 2017

I don't think that's a great option. There is no reason implementation of inter-character and ruby annotation container should be tied together.

@upsuper
Copy link
Member Author

upsuper commented Sep 11, 2017

I actually start wondering whether inter-character ruby is a good idea at all, now.

Majority of use case of inter-character ruby can be achieved by something like:

<!DOCTYPE html>
<meta charset="UTF-8">
<style>
ruby {
  display: inline-block;
  width: 1.4em;
}
rt {
  display: inline-block;
  writing-mode: vertical-rl;
  text-orientation: upright;
  font-size: 30%;
  vertical-align: middle;
}
p {
  font-size: 72px;
}
</style>
<p>
  <ruby><rt>ㄨㄛˇ</rt></ruby><ruby><rt>ㄑㄧˇ</rt></ruby><ruby><rt>ㄌㄞˊ</rt></ruby><ruby><rt>˙ㄌㄜ</rt></ruby><ruby><rt>ㄨㄛˇ</rt></ruby><ruby><rt>ㄑㄧˇ</rt></ruby><ruby><rt>ㄌㄞˊ</rt></ruby><ruby><rt>˙ㄌㄜ</rt></ruby>
</p>

which just works in every browser nowadays. (I don't think the width on ruby should be necessary, but there might be some bug in Gecko which stops it from working as expected. That should be investigated separately.)

There are issues around this approach, e.g. justification doesn't work, letter-spacing doesn't work. But those can be fixed independently, e.g. via treating inline-blocks as U+FFFD in the corresponding algorithms (which should be desirable in general I suppose).

I have a feeling that baking this feature into CSS itself directly is more complicated than it's worth, especially given that the testcases can already be done with some stable CSS features without much hack.

@bobbytung
Copy link

bobbytung commented Sep 11, 2017 via email

@upsuper
Copy link
Member Author

upsuper commented Sep 11, 2017

But in this way, ruby will be separated with Hanzi when line-break. It is quite important requirement for inter-character.

With inline-block, it wouldn't. But letter spacing could be a real problem. If I understand correctly, people may want consistent spacing between hanzis regardless whether one has inter-character ruby.

@kahsieh
Copy link

kahsieh commented Sep 11, 2017

@upsuper It seems I'm only able to get the example working in Firefox and Edge (not Chrome or Safari), and even then, the annotation is aligned to the baseline despite vertical-align: middle being specified. Line breaking works properly, though, and perhaps something can be done about the alignment.

@frivoal
Copy link
Collaborator

frivoal commented Feb 2, 2021

@upsuper, In https://lists.w3.org/Archives/Public/www-style/2015Mar/0202.html you said:

Alternatively, we should specify that writing-mode should be the same
between ruby container, ruby base container and ruby text container, if
ruby-position is over/under.

We have that already, given that writing-mode is specified not to apply to base containers and annotation containers. Given that, isn't the circularity you were worried about solved already? In a base container, the writing mode is that of the ruby container, and in a annotation container, the writing mode depends only on ruby-position. No? As long as dropping ruby-position:inter-character isn't an option anymore (and I think it isn't, given that webkit has been shipping, and that you agreed in that same email), is there anything left to solve here?

@upsuper
Copy link
Member Author

upsuper commented Feb 7, 2021

The circularity is not solved.

In an annotation container, the writing-mode depends on ruby-position, but computing display depends on writing-mode, without figuring out display first you don't know it's an annotation container, and without knowing it's an annotation container, you don't know whether ruby-position should change the writing-mode. It's still a circular dependency between display, writing-mode, and ruby-position.

As I should have mentioned before, this isn't strictly unsolvable, because as far as display: ruby-text-container can't be changed by writing-mode, and nothing else can be computed to display: ruby-text-container based on writing-mode, it's probably fine. It just feels a bit fishy to have this. But probably it's probably fine.

@frivoal
Copy link
Collaborator

frivoal commented Feb 9, 2021

How about we solve this overall question of writing modes for inter-character annotations is by:

The writing-mode of a ruby annotation is computed to vertical-rl if the
ruby-position of parent (i.e. the ruby-position of the annotation container) is inter-character

This is different from the current spec, which computes on the annotation container itself. Upsides (?) are:

  • No need to worry about someone manually changing the writing-mode on the annotation itself
  • Interdependency on an element is between writing-mode and display only, as we're using ruby-position of the parent.

Although display and writing-mode would depend on each other on a single element, there is no loop: writing-mode would depend on display only if display is ruby-annotation, and in this case display does not depend on writing-mode. If needed, we could also make orthogonal writing-mode affecting display a used-value time operation, since 'display' doesn't inherit.

This works fine if:

  • neither the annotation nor its annotation containers are anonymous
  • the annotation container is anonymous (just go up one level to the ruby container)
  • the annotation is an anonymous wrapper around white space (there's no structure below the annotation within which we should worry about inheritance)

The only odd case is this:

<ruby style="inter-character">hello<rtc>I am <em>really</em> messed up</ruby>

or equivalently this:

<ruby>hello<rtc style="inter-character">I am <em>really</em> messed up</ruby>

Inheritance works on the element tree, so the forced vertical writing mode on the rtc doesn't propagate down to the <em> element, which then is an orthogonal horizontal-tb inline-block inside the vertical annotation.

I suppose we could make an exception and ask inheritance to special case this, but I don't think we need to: there's no reason to use that particular markup pattern. Authors should instead use this simpler markup, which works just fine.

<ruby style="inter-character">hello<rt>This is <em>fine</em>.</ruby>

And if they really want an rtc element there for some reason, then they should have an explicit rt element as well.

With that in mind, this proposal solves all cases involving reasonable markup, without going into complicated inheritance or computed value shenanigans.

See also prevous www-style commentary https://lists.w3.org/Archives/Public/www-style/2014Dec/0245.html (thread) and https://lists.w3.org/Archives/Public/www-style/2015Feb/0358.html

@upsuper
Copy link
Member Author

upsuper commented Feb 13, 2021

I think that could work. While it's still unfortunate to see writing-mode and display depend on each other, but it's probably fine.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-ruby-1] Propose to treat rtc with orthogonal writing-mode to be inter-character rather than using ruby-position, and agreed to the following:

  • RESOLVED: Writing mode of a ruby annotation is forced to vertical rl if the parent ruby position is intercharacter
The full IRC log of that discussion <dael> Topic: [css-ruby-1] Propose to treat rtc with orthogonal writing-mode to be inter-character rather than using ruby-position
<dael> github: https://github.com//issues/1773
<fantasai> proposal at https://github.com//issues/1773#issuecomment-775694005
<dael> fantasai: I figured we would go over proposal and decide if we want to accept
<dael> fantasai: Proposal is here ^
<dael> fantasai: It's that writing mode of ruby annotation computes to vertical rl if the ruby position of parent is intercharacter
<dael> fantasai: Type of ruby that goes down side of element. Picture link
<fantasai> https://www.w3.org/TR/css-ruby-1/#ruby-position-inter-character-annotation
<dael> fantasai: No matter text they're always on right and always top to bottom
<dael> fantasai: Had difficulties to get writing mode and ruby position to interact. Proposal is to use the ruby position of the annotation container rather than annotation because container easier to look up
<Rossen_> q?
<dael> fantasai: Proposing that if this box is a ruby annotation and it's parent, annotation container, is intercharacter the writing mode of this box computes to rl
<dael> fantasai: Odd cases you can get into. For example, set intercharacter and have anon boxes.
<dael> fantasai: For the most part think works in most cases
<dael> fantasai: Prop to change spec to say this. Wnat to ask if there are concerns or a better solution
<dael> florian: xidorn finds that it would work. That was encouraging, but about a year ago
<dael> fantasai: Don't have to resolve today but should resolve
<dael> iank_: All this means is that for computing writing mode we depend on the tag name and the parent style if it has interstyle set?
<dael> fantasai: did you say tag name?
<dael> iank_: Just the display of the box?
<dael> fantasai: Display of box and parent
<dael> iank_: Okay. Seems fine from style adjuster
<dael> florian: Interaction slightly annoying, but no loops
<Rossen_> q?
<dael> Rossen_: Other opinions or questions?
<dael> Rossen_: I prefer if we try and have a resolution here. Even if we have to revisit later
<dael> florian: Would be nice if spec could have latest thinking. Can always speak again
<dael> Rossen_: It's been a year and no other suggestions put forward. This will be good forcing function
<dael> Rossen_: Treating rtc with orthogonla writing mode to be intercharacter?
<dael> fantasai: Prop: Writing mode of a ruby annotation is forced to vertical rl if the parent ruby position is intercharacter
<dael> Rossen_: Objections?
<dael> RESOLVED: Writing mode of a ruby annotation is forced to vertical rl if the parent ruby position is intercharacter

@frivoal
Copy link
Collaborator

frivoal commented Feb 3, 2022

Fixed in 74885da

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

8 participants