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-writing-modes] Question about implementability of the "different writing-mode value than its containing block" section of the spec #1212

Closed
kojiishi opened this issue Apr 13, 2017 · 18 comments

Comments

@kojiishi
Copy link
Contributor

kojiishi commented Apr 13, 2017

Filing on behalf of @bzbarsky, from a www-style thread:

https://drafts.csswg.org/css-writing-modes-3/#block-flow says (not directly linkable):

If a box has a different writing-mode value than its containing block:
If the box has a specified display of inline, its display computes to inline-block. [CSS21]
If the box is a block container, then it establishes a new block formatting context.
More generally, if its specified inner display type is flow, then its computed inner display type becomes flow-root. [CSS-DISPLAY-3]

I have several concerns about this language:

  1. Determining the containing block requires knowing the computed
    values of various properties. Requiring knowledge of the containing
    block to determine computed display means that UAs can't cleanly
    separate a style computation pass from other things. This is likely to
    be quite difficult to implement in practice, though also in practice it
    might be hard to observe because most if not all of the things that make
    the containing block not match the thing you inherit style from fall
    afoul of concern List of changes from 3 #2.

  2. This requirement directly contradicts the requirements laid out in
    https://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo or equivalent at
    https://drafts.csswg.org/css-display-3/#transformations.
    Specifically, consider this testcase:

   <div style="position: relative; writing-mode: horizontal-tb">
     <div style="writing-mode: vertical-rl">
       <span style="writing-mode: vertical-rl; position: 
absolute">Text</span>
     </div>
   </div>

What is the computed display value of the "span"? Is it "inline-block"
or "block"? The writing-modes spec says "inline-block"; the display
spec says "block". Nothing reconciles the disagreement. In practice,
looks like at least Chrome and Firefox compute to "block" in this
situation; I haven't tested other UAs in ways that I consider reliable.
I haven't tested whether hypothetical box determination here uses
"inline" or "inline-block" as the display type; that obviously needs to
be defined too.

In practice, what Gecko seems to implement here is to start at the thing
you inherit style from (some handwaving about ::first-line here), and
walk up the inheritance chain to the first thing with display not equal
to "contents". Then if the writing mode doesn't match that set
display to "inline-block". And this happens before blockification
triggered by float/position. I haven't checked what we do for the
hypothetical box.

If this is in fact black-box equivalent to what the spec is trying to
define, it might be worth rephrasing it in ways that don't break the
layering of property value computation, so we don't accidentally make it
not black-box equivalent and not very implementable. If it's not
black-box equivalent, I'd like to see what a testcase to distinguish the
two options looks like and see what UAs do with that testcase.

-Boris

P.S. Obviously there's an issue here when a run-in has different
writing-mode than the block it runs into. The display and writing-mode
specs don't consider this case. I recommend it be resolved by removing
run-ins. ;)

@kojiishi
Copy link
Contributor Author

Thank you for the great feedback, @bzbarsky.

In practice, what Gecko seems to implement here is to start at the thing
you inherit style from (some handwaving about ::first-line here), and
walk up the inheritance chain to the first thing with display not equal
to "contents".

Blink checks parent too, not containing block. I believe WebKit does so too.

Is the logic mentioned here the same as blockificaiton? If so, can we say "blockify if the element has different writing-mode from its parent"?

If different, is the fix of s/containing block/parent box/ appropriate?

I'm not very familiar with run-in and details of display types, advice appreciated.

/cc @fantasai @rune-opera

@bzbarsky
Copy link

Blink checks parent too

On the box tree. That may not match the Gecko behavior, depending on how "parent" is defined and how various cases involving anonymous boxes are handled.

Is the logic mentioned here the same as blockificaiton?

No, it's not. blockification never leads to an inline-outside display type, while the logic here very much does (inline-block).

If different, is the fix of s/containing block/parent box/ appropriate?

"parent box" has the same problem as "containing block", from my point of view: it's a layering violation.

Worse yet, nothing in the CSS specs really defines "parent box" last I checked, though admittedly I last checked a while ago.

@kojiishi
Copy link
Contributor Author

On the box tree.

Oh, right. Blink is still in the middle of separating style/box tree (AFAIU) and we can do it only after it's done.

I checked CSS Cascade but all it says is "parent" or "parent element". Maybe we should follow that, and fix CSS Cascade to describe it better.

Is the logic mentioned here the same as blockificaiton?

No, it's not. blockification never leads to an inline-outside display type, while the logic here very much does (inline-block).

Oh, I see. I thought blockification changes inline to inline-block but it looks like I was too biased to writing mode roots.

So:

  • Change "containing block" to "parent element".
  • File a bug to CSS Cascade to define "parent element", including re-considering the terminology (since element is the same terminology in DOM)

Are these correct actions to solve this?

@kojiishi
Copy link
Contributor Author

On second thoughts, it may be better to avoid using fragile terms and say "the parent it inherits from", until CSS cascade defines.

We'll have F2F next week, hopefully we can get wider attention on this there.

@bzbarsky
Copy link

I checked CSS Cascade but all it says is "parent" or "parent element".

"parent element" is a perfectly well-defined thing. It's just not the right one for the writing-mode case, not least because of display:contents.

since element is the same terminology in DOM

YES! "parent element" in CSS Cascade terms is the same exact concept as "parent element" in the DOM.

and say "the parent it inherits from"

Gives the wrong behavior for display:contents, at least.

Please stop flailing and sort out what the behavior should actually be instead of just guessing and checking....

@kojiishi
Copy link
Contributor Author

kojiishi commented Apr 13, 2017

I can't understand what your last paragraph means with my English skill, I guess I should stop asking and you want to discuss with style experts?

@rune-opera @shans can you help?

@bzbarsky
Copy link

I think the right thing here is to not try writing spec language until we have a clear description of what behavior we're actually after, possibly with testcases illustrating it. Once we all agree on what the right behavior is (and it's not clear to me whether shipping implementations even agree on that), we can try to figure out how to spec it.

@fantasai
Copy link
Collaborator

Given that a mismatched writing mode on an inline box results in it becoming a block container, we can assume that checking writing-mode on the parent of an inline is equivalent to checking writing-mode on its containing block. So we can update the spec to check the parent box, and that solves that problem.

Wrt the conflict with the blockification rules, the intent of this rule is that it only affects the internal display type, i.e. if it is flow it becomes flow-root, and is otherwise unchanged. The outer display type is handled by blockification rules; they don't affect the inner display type. (CSS2.1 mixes both, but L3 separates these concepts.)

@bzbarsky
Copy link

So we can update the spec to check the parent box

Again, that makes computed style depend on box construction. This is undesirable, and should be avoided if possible.

But also, I don't think it's necessarily true that the "parent box" and "containing block" have the same writing mode, depending on how "parent box" is defined. Which it's not, really, last I checked.

Wrt the conflict with the blockification rules, the intent of this rule is that it only affects the internal display type

OK, that's not what the spec says right now. Fixing that would help, yes.

@bzbarsky
Copy link

Er, also, blockification rules absolutely affect the inner display type!

@fantasai
Copy link
Collaborator

So we can update the spec to check the parent box
Again, that makes computed style depend on box construction. This is undesirable, and should be avoided if possible.

Aside from display: contents, what else would make the parent box not the parent element?

Er, also, blockification rules absolutely affect the inner display type!

Okay, yeah, blockification affects the inner display type, but there's no merge conflict here. :) Although I'm not sure that this actually needs to happen; flow blocks can behave the same as flow-root in some cases, like floats and suchlike... changing the inner display type doesn't seem necessary, and certainly can't be a computed value time operation given https://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo That's maybe a separate bug.

fantasai added a commit that referenced this issue Apr 19, 2017
@bzbarsky
Copy link

Aside from display: contents, what else would make the parent box not the parent element?

It depends on how you define "parent box", obviously. I have yet to see a definition, so I can't tell you for sure. But in terms of implementations, out-of-flows have a parent box that is not their parent element in at least some implementations.

Also, the right question is "what else that might ever get defined in CSS would make the parent box not the parent element?" That is, if the intent is for computed style to not depend on box construction, but the definition is done in terms of boxes, it becomes very hard to implement computed style without reference to boxes that is not just going to break as new CSS features are added.

changing the inner display type doesn't seem necessary

Um... I don't follow. If I absolutely position a thing that's display:inline, its inner display had better change. That's how it's been specced forever, how it's implemented in all browsers, and websites depend on it. Am I just missing something about the change you just made to css-display and how it relates to this case?

@fantasai
Copy link
Collaborator

"Parent box" is the parent in the box tree, as usual. It's not necessarily the containing block. So for a float inside a SPAN, it's the SPAN, not the P that contains the SPAN. This is fine; this clause doesn't apply to out-of-flows, it only applies to in-flow display: inline boxes.

Um... I don't follow. If I absolutely position a thing that's display:inline, its inner display had better change. That's how it's been specced forever, how it's implemented in all browsers, and websites depend on it. Am I just missing something about the change you just made to css-display and how it relates to this case?

There are a number of cases (e.g. overflow, float, position) where the inner display type behaves as flow-root, even when its display value is flow. This is called out in https://www.w3.org/TR/css-display-3/#valdef-display-flow There's no need for the display value to change here, hence I deleted the sentence that implied that.

@bzbarsky
Copy link

"Parent box" is the parent in the box tree, as usual

Where is this concept defined? I think the use of "as usual" here is a bit odd, given again that I don't think this stuff is defined anywhere.

This is fine; this clause doesn't apply to out-of-flows, it only applies to in-flow display: inline boxes.

Why? What prevents CSS from adding a feature that makes something out-of-flow without blockifying?

If the intent is that this is only applied to in-flow inlines, that needs to be pretty explicitly stated.

There's no need for the display value to change here

Ah, I see. "flow" could mean "acts like a block on the inside" or it could mean "acts like an inline on the inside". That's ... pretty odd for a inner display value behavior. :( I would have expected that things that act like inlines on the inside and things that act like blocks on the inside would have different display-inside values.... Anyway, this is getting a bit off-topic. I filed #1246 on the other issue I see with this stuff that is even more off-topic for this discussion...

I would like to reiterate that I would like computed values to be defined without reference to the box tree.

@fantasai
Copy link
Collaborator

If the intent is that this is only applied to in-flow inlines, that needs to be pretty explicitly stated.

Sure, can do that.

I would like to reiterate that I would like computed values to be defined without reference to the box tree.

Would nearest non-display:contents ancestor work for you? Because that's literally the same thing. :)

@bzbarsky
Copy link

Would nearest non-display:contents ancestor work for you?

Yes, it would. As I said in the beginning, that's what Gecko already implements anyway. ;)

triple-underscore added a commit to triple-underscore/triple-underscore.github.io that referenced this issue Apr 19, 2017
…ication turning `flow` into `flow-root` as this is inconsistent with CSS2.1§9.7 https://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo and also unnecessary. w3c/csswg-drafts#1212
@fantasai
Copy link
Collaborator

fantasai commented May 2, 2017

Alright, fixed in b59c4e2 Let me know if it's sufficiently well-specified for you, @bzbarsky. :)

@bzbarsky
Copy link

bzbarsky commented May 2, 2017

That looks pretty good, thank you!

triple-underscore added a commit to triple-underscore/triple-underscore.github.io that referenced this issue May 3, 2017
…59c4e2

Use box parentage instead of containing block, since in the cases where
any of these rules take effect, the same output would result. Fixes
w3c/csswg-drafts#1212 .

+内部的編集
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

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy