w3c / csswg-drafts

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

[css-ruby-1] Breaks within implicit bases is not Web-compatible #10073

Open fantasai opened 8 months ago

fantasai commented 8 months ago

The suggested UA default stylesheet for ruby includes

rb   { display: ruby-base; white-space: nowrap; }

but this is not sufficient because it doesn't disable wrapping within implicit ruby bases (which is required for Web-compat).

fantasai commented 8 months ago

The simplest solution would be to disallow breaking within ruby bases (as a layout constraint), but this means the author has no way to allow it if that's needed.

The alternative solution, which would allow the author to override as necessary (easily if they use rb, less so if they don't), would be to

hober commented 8 months ago

Could we add a pseudo-element that matches any ruby base, be they explicit or implicit? Then the UA sheet could simply say ::ruby-base { display: ruby-base; white-space: nowrap; } and this could be overrideable by authors.

anttijk commented 8 months ago

That wouldn't solve the <ruby><span>don't break me</span><rt>annotation</rtr></ruby> case without something additional because white-space: nowrap wouldn't inherit from the pseudo element to the span and it would still break.

Also I don't see the need. If an author wants more control they could use explicit <rb>.

hober commented 8 months ago

That wouldn't solve the <ruby><span>don't break me</span><rt>annotation</rtr></ruby> case without something additional because white-space: nowrap wouldn't inherit from the pseudo element to the span and it would still break.

Ugh, yeah, good point.

Also I don't see the need. If an author wants more control they could use explicit <rb>.

I suppose we ought to add <rb> to HTML, then. :)

fantasai commented 7 months ago

Elements inherit from ::first-line so if we were to define ::ruby-base we would want to define it that way. (Otherwise a lot of things won't work properly, e.g. color or font.) But it maybe depends how much appetite implementers have for implementing such a pseudo-element.

css-meeting-bot commented 6 months ago

The CSS Working Group just discussed [css-ruby-1] Breaks within implicit bases is not Web-compatible, and agreed to the following:

The full IRC log of that discussion <dbaron> fantasai: In suggested UA style sheet, we had rb { white-space: nowrap}. Most ruby bases don't have an rb element for reasons that I disapprove of, but it's where we're at.
<dbaron> fantasai: We wanted to allow bases to wrap... so we don't want to forbid wrapping within bases entirely with no way to change it.
<dbaron> fantasai: There are different approaches we could take to solve this.
<dbaron> fantasai: One is to have the UA apply text-wrap-mode to anonymous... but if we did that author wouldn't be able to allow wrapping.
<dbaron> fantasai: We could say anonymous ruby bases have text-wrap-mode: nowrap on them, and if author wants to wrap the base they could use an rb or a span.
<dbaron> fantasai: ANother option is to have a pseudo-element for anonymous ruby bases.
<dbaron> florian_irc: if a pseudo, then all ruby bases whether anonymous or not
<dbaron> fantasai: or that
<florian_irc> q+
<dbaron> fantasai: Third option, have white-space: normal compute to nowrap on ruby bases and magically inherit that way. So unless you explicitly set it to something else it will be nowrap.
<astearns> ack florian_irc
<fantasai> florian_irc: I think a pseudo-element would be overkill
<fantasai> florian_irc: if just for this use case
<fantasai> florian_irc: so first option would make sense
<fantasai> florian_irc: but there are other use cases for a ruby base pseudo-element
<astearns> ack dbaron
<fantasai> florian_irc: so maybe we get one later; but that's complicated so wouldn't start there
<fantasai> 1. apply `text-wrap-mode: nowrap` to anonymous bases
<fantasai> 2. add a ::ruby-base pseudo-element and apply it that way
<fantasai> 3. make `white-space: normal` compute to `nowrap` on ruby bases
<emilio> I think that's the simplest approach
<fantasai> dbaron: I also lean towards the first proposal
<fantasai> dbaron: the one other thought is, I'm concerned about making pseudo-element apply to all ruby bases whether anonymous or not
<fantasai> dbaron: as of right now we don't have a pseudo-element that also matches real elements
<fantasai> dbaron: there are some proposals that might take us down this path, but it's got some interesting issues and wouldn't want to go down this path without thinking about it carefully first
<fantasai> florian_irc: fair neough
<fantasai> s/neough/enough/
<fantasai> astearns: sounds like we're converging on 1st option
<fantasai> astearns: personally concerned about that, because we're dictating styling that you can only change by changing your markup
<fantasai> astearns: which seems like the wrong path
<fantasai> astearns: should have a way to override the thing we're applying to the anonymous bases
<fantasai> astearns: but if ppl want that, we could add the pseudo element
<fantasai> florian_irc: that said, you're not changng your markup to something unrelated, if you elide markup you have fewer things to style
<dbaron> fantasai: two points:
<astearns> ack fantasai
<dbaron> fantasai: one, the suggestion about computing text-wrap-mode differently... we'd make text-wrap-mode: normal | wrap | no-wrap
<dbaron> fantasai: normal would be the initial value and mean wrap except for a ruby base
<dbaron> fantasai: so if you wanted to style it differently you could set text-wrap-mode: wrap on the ruby element
<dbaron> fantasai: second, we wouldn't have this problem if html parsers injected rb tags into ruby, which they should have done, and I'm still annoyed about that.
<dbaron> florian_irc: is that still fixable?
<dbaron> fantasai: I don't know. We'd have to analyze existing content to see what kinds of selectors are being used.
<dbaron> fantasai: if people are using child selectors in combination with ruby, those could break
<astearns> ack dbaron
<dbaron> fantasai: I don't expect people to do that unless they're doing something fancy with rp
<fantasai> dbaron: It feels less costly to do a pseudo-element than to do the extra value of text-wrap-mode
<emilio> q+
<fantasai> dbaron: so given choice between those two, I would lean towards pseudo-element
<astearns> ack emilio
<fantasai> fantasai: implementation cost aside, agree it's a lower cost to authors, since they only encounter the complication if they're working in ruby (which is highly specialized)
<fantasai> emilio: analogy with table parts is good, if you wanted you can just write it
<fantasai> fantasai: tables inject tbody even if you don't write it
<fantasai> emilio: I mean, if you set 'display: table-cell' on a random element no way to style the table
<fantasai> emilio: I agree with styling the anonymous boxes, it's consistent
<fantasai> florian_irc: and also it's compatible with extending to introduce a pseudo-element
<fantasai> florian_irc: and it's also compatible with fixing the HTML parsing, if we're ever able to do that
<fantasai> PROPOSED: Adopt `text-wrap-mode: nowrap` styling to anonymous ruby bases
<fantasai> ruby > :not(rb, rbc, rtc, ruby) { text-wrap-mode: nowrap; }
<fantasai> fantasai: we'd have to add this rule also, because real elements can't inherit from anonymous
<fantasai> dbaron: a bit concerned about that selector because it looks expensive from perf perspective ... unsure for current engines
<fantasai> dbaron: idk if will require parent of every element
<emilio> q+
<astearns> ack fantasai
<fantasai> emilio: that rule is not great
<fantasai> RESOLVED: Style anonymous bases with text-wrap-mode: nowrap as described in https://github.com/w3c/csswg-drafts/issues/10073#issuecomment-1995455391
<dbaron> (I'm a little worried the 2 things are tied together and we may need to reconsider.)
<fantasai> emilio: regarding performance, it's probably not as terrible as it used to be, but only probablistic filtering
<fantasai> emilio: overall I don't think it's great
<fantasai> emilio: can we set nowrap on the ruby element itself?
<fantasai> fantasai: ruby itself needs to be able to wrap
<fantasai> emilio: can we explicitly list stuff?
<fantasai> florian_irc: all possible inline elements?
<fantasai> astearns: can it be magic?
<fantasai> emilio: not really great...
<fantasai> astearns: ok, out of time. Can either leave open or resolve to add it and then work through the perf concerns.
<fantasai> astearns: what's the preference?
<fantasai> dbaron: lean towards leaving it open
<fantasai> RESOLVED: unresolve previous resolution
frivoal commented 6 months ago

If ruby > :not(rb, rbc, rtc, ruby) { text-wrap-mode: nowrap; } is problematic from a performance point of view, could we go with:

ruby > * { text-wrap-mode: nowrap; }
ruby, rbc, rtc { text-wrap-mode: inherit; }

or is that no better?

fantasai commented 6 months ago

I'm not sure that's much better. The problem IIRC is the child selector lookup on a universal subject (?).

fantasai commented 6 months ago

(Also it would have to be ruby, rbc, rtc { text-wrap-mode: inherit; } or unset, not wrap.)

anttijk commented 6 months ago

ruby > :not(rb, rbc, rtc, ruby) is ok from perf perspective because it is easily eliminated by the ancestor filter in non-ruby subtrees. I think this is true for all engines.