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-display] Blockification doesn't seem backwards-compatible for inline-blocks #1246

Closed
bzbarsky opened this issue Apr 19, 2017 · 13 comments
Closed

Comments

@bzbarsky
Copy link

What happens if I absolutely position an inline-block? Per current browser behavior it becomes a "block". Per the css-display-3 draft it becomes a "flow-root", if blockification only affects display-outside. Is that a purposeful behavior change?

@fantasai
Copy link
Collaborator

Not an intentional change. :(

@fantasai
Copy link
Collaborator

I believe this is fixed in 4d50007

Please re-open if that's not the case and there's something I missed.

@bzbarsky
Copy link
Author

I think one of us is missing something, but I'm not sure whether it's me or you. ;)

Per the table at https://www.w3.org/TR/css-display-3/#legacy-display 'inline-block' "behaves as 'inline flow-root'". But per https://www.w3.org/TR/css-display-3/#the-display-properties the computed value of 'display' is the specified value... So if I have 'inline-block' specified, it computes to 'inline-block', not 'inline flow-root'. OK, fine.

But then https://www.w3.org/TR/css-display-3/#transformations talks about just changing the outer display to 'block' and does not change the inner display. What does that actually mean in terms of the computed value? I see a few options:

  1. The precomposed value is decomposed to two keywords, the outer display is changed to 'block', and the new computed value is the resulting two-keyword value. That would give 'block flow-root'.
  2. The precomposed value is decomposed to two keywords, the outer display is changed to 'block', and the new computed value is the precomposed value that corresponds to the new two-keyword value. That would give 'flow-root'.
  3. The computed value is 'block'. This is what browsers do right now, but I see no way to get there via the spec as currently written.

Note that the used value is likely 'block flow-root' in all cases, because things that cause blockification also lead to flow-root behavior. The question is what the computed value is.

@bzbarsky bzbarsky reopened this Apr 19, 2017
@bzbarsky bzbarsky changed the title [css-display-3] Blockification doesn't seem backwards-compatible for inline-blocks [css-display] Blockification doesn't seem backwards-compatible for inline-blocks Apr 19, 2017
@Loirooriol
Copy link
Contributor

The spec says "Computed value: as specified". So the display property sets the display type, but transformations of the display type don't affect the computed value of display. That's how I read it, but clearly it's not what browsers do.

@bzbarsky
Copy link
Author

The spec also explicitly says that the transformations transform the computed value. Yes, the spec is kinda self-contradictory; not the first time.

@fantasai
Copy link
Collaborator

Okay, so, there are two ways we can handle this:

  • Treat inline-block and inline flow-root as syntactically equivalent. Make both of them blockfy as display: block.
  • Treat inline-block and inline flow-root as syntactically distinct. Make inline-block blockify as display: block; inline flow-root will blockify as flow-root.

The advantage of the first approach is that the various inline-foo models are all syntactic equivalents of their two-keyword inline foo forms. This is a nice consistency to have.

The advantage of the second approach is that, aside from the inline-block keyword itself, everything maintains its display type as specified with the mere substitution of block for inline or run-in (and shortening of serialized output per normal CSSOM rules).

Is there a reason to prefer one solution over the other?

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Blockification doesn't seem backwards-compatible for inline-blocks, and agreed to the following resolutions:

  • RESOLVED: we are provisionally going with option b
The full IRC log of that discussion <astearns> topic: Blockification doesn't seem backwards-compatible for inline-blocks
<astearns> github topic: https://github.com//issues/1246
<tantek> TabAtkins: when you blockify an inline-block what happens
<tantek> TabAtkins: right now blockification just changes the outer display type to block
<tantek> TabAtkins: in particular for an inline-block, it becomes a block flow root
<tantek> TabAtkins: which when you ask its display type it says block flow root
<tantek> TabAtkins: but for legacy reasons it has to be block
<tantek> TabAtkins: we prob need to do same sort of exception
<fantasai> issue under discussion https://github.com//issues/1246#issuecomment-301634850
<tantek> TabAtkins: when you blockify an inline-block, it becomes a plain block
<tantek> TabAtkins: now that we have the opposite thing, it is reasonably consistent
<tantek> fantasai: this is on the agenda because it is more complicated than that
<tantek> fantasai: we can treat inline-block and inline-flow-root as the same
<TabAtkins> https://github.com//issues/1246#issuecomment-301634850
<TabAtkins> Two possibilities ^^^
<tantek> fantasai: alternatively we can treat ... as ...
<tantek> fantasai: (buffer overrun)
<fantasai> Treat inline-block and inline flow-root as syntactically equivalent. Make both of them blockfy as display: block. Treat inline-block and inline flow-root as syntactically distinct. Make inline-block blockify as display: block; inline flow-root will blockify as flow-root.
<tantek> fantasai: the advantage of first approach, is that the inline-foo are al syntactic equivs
<tantek> fantasai: the advantage of the second approach is ...
<jensimmons> I vote (b). It makes sense that the flow-root-ness would stick around, imho.
<tantek> Rossen: the 2nd approach will round trip nicer through the OM right?
<tantek> TabAtkins: doesn't matter yet
<tantek> Rossen: the distinction between display outside and inside, which one will round trip more gracefully
<tantek> fantasai: we have defined all the inline-* to all the inline-space-* etc.
<tantek> fantasai: we didn't have the display module in time to avoid the inline-... and inline-...
<tantek> fantasai: if you have a inline-space-table and read it back out in the OM it will take the shortest most compat form and return inline-table
<tantek> fantasai: if we want the 2nd approach we have to not convert, maintain as a separate thing, e.g. inline-flex two ways to syntactically define it and would not collapse
<tantek> Rossen: if we blockify a display block rather than inline flow root, and you read back the display and set it back on the same element, you are now going to turn an inline block into a block
<tantek> fantasai: yes that happens right now
<tantek> fantasai: for flexes and other things that blockify
<tantek> fantasai: happens in 2.1 and flex and grid
<fantasai> (via abspos, floats, etc.)
<tantek> Rossen: my udnerstanding is ... blockification as opposed to flow root in terms of where positioned, it will try to be block as much as possible
<tantek> TabAtkins: I am confused about what youa re trying to say Rossen
<tantek> TabAtkins: anything inline-ish becomes blockish
<tantek> TabAtkins: inline-root becomes flow-root
<tantek> TabAtkins: inline-block becomes block
<tantek> Rossen: the inline block will become a flow root?
<tantek> TabAtkins: yup
<tantek> Rossen: if I read back (static) what will be different
<tantek> Rossen: which one of those will be (static) be better (siren)
<tantek> Rossen: which of those two if re-parented, if any will have more expected behavior
<tantek> TabAtkins: the flow root one will
<tantek> TabAtkins: that is the reason why blockificiation turns a inline-block into a flow root
<tantek> Rossen: ok that is why I am leaning more towards flow root
<tantek> TabAtkins: so that sounds like you are suggesting 2nd one
<tantek> TabAtkins: inline-block becomes block for legacy reasons
<fantasai> Option A: inline-block -> block; inline flow-root -> block
<tantek> TabAtkins: but inline flow root becomes block flow root
<fantasai> Option B: inline-block -> block; inline flow-root -> flow-root
<tantek> astearns: any other conversation on this
<tantek> astearns: any obj to inline space flow become inline flow root?
<tantek> fantasai: main concern, we no longer treat inline-* and inline space * as equiv
<tantek> TabAtkins: for this specific value
<tantek> astearns: in part for legacy reasons
<tantek> TabAtkins: entirely for legacy reasons
<tantek> fantasai: but that means if you compute inline foo ...
<tantek> fantasai: but now we have to keep them distinct in the OM as well
<tantek> TabAtkins: yeah we will have to
<tantek> astearns: is your desire for syntactic equiv an obj?
<tantek> fantasai: no, just wanted to make it clear
<tantek> dbaron: it is an extra point of confusion in that before we could say these two things are equivalent
<tantek> dbaron: but it is now more complicated because in this one case they are not
<tantek> dbaron: the other q is whether you maintain separate computed values for just this one case or the whole possible space of values
<tantek> TabAtkins: hmm
<tantek> astearns: i would expect we would maintain equiv where we can and this is the exception that proves the rule
<tantek> astearns: so
<dbaron> I'm not crazy about the idea, but I'm not objecting to it...
<tantek> astearns: do we resolve to use option b and work through the details? or shall we spend some more time working the details in the issue and come back to this?
<tantek> TabAtkins: I think we should resolve on b and I can open a separate issue on the point that dbaron just raised
<tantek> TabAtkins: I'll open a separate issue for that
<tantek> fantasai: my concern is that if we go with option b and then we have the other discussion, then we find we don't like and want to come back to option a
<tantek> fantasai: b implies at least two things that a does not in terms of how other values behave
<tantek> fantasai: but that was not discussed in the issue in terms of a vs b
<tantek> astearns: fantasai do you want to postpone making the resolution? or ok to have provisional resolution for b?
<tantek> fantasai: that is a more important discussion to have
<tantek> fantasai: and then decide this issue because I think it is less important
<tantek> fantasai: the resolution here should depend on that discussion
<tantek> TabAtkins: I disagree but I have no problem with changing the resolution later
<tantek> TabAtkins: if based on another discussion we decide we resolved wrong
<tantek> astearns: when you open the new issue TabAtkins please link back to this one, so once we decide on the other one we can see if this resolution still holds
<tantek> action TabAtkins open new issue on what we are doing with the syntax equivalencies and linking back to this issue so we can revisit this resolution
<trackbot> Created ACTION-852 - Open new issue on what we are doing with the syntax equivalencies and linking back to this issue so we can revisit this resolution [on Tab Atkins Jr. - due 2017-06-07].
<tantek> astearns: any obj to resolving on opt b for cur issue?
<tantek> RESOLVED: we are provisionally going with option b
<tantek> astearns: next topic

@SelenIT
Copy link
Collaborator

SelenIT commented Jun 1, 2017

Note that the used value is likely 'block flow-root' in all cases, because things that cause blockification also lead to flow-root behavior.

I believe that the quoted part is really important. Before flow-root value was introduced, using block as a value to use/report and describing that it also establishes the new BFC in prose was the only option. Now, when we have the value that describes both things, what stops us from using flow-root for both computed and used values in all the relevant cases (except legacy reasons)?

@bzbarsky
Copy link
Author

bzbarsky commented Jun 1, 2017

The computed value affects not just what's "reported", but also what's inherited.

So if you have a thing that gets blockified and a child that has "display: inherit", should that child end up as a flow root or not? Why or why not?

(And of course "legacy reasons" might trump everything else in practice.)

@tabatkins
Copy link
Member

Inheritance isn't even a big deal, honestly (who the hell writes display: inherit? don't tell me, it'll just depress me).

The big deal is serialization; things that used to serialize to "block" have to continue to do so, but if they become block flow-root they'll serialize to "flow-root" instead.

Future things that blockify might want to explicitly FC-ify as well, which can change the serialization just fine, but we have a lot of legacy to think about.

@fantasai
Copy link
Collaborator

fantasai commented Jul 5, 2017

Thinking about this more, I have some very strong reservations to the resolution recorded here. Specifically, because we do some automatic transformations (as when 'writing-mode' or ruby fixup turns things into inline blocks), and a) it's not clear to me which serialization we choose or why and also b) it creates an opportunity for inconsistencies across the specs, if different ones choose different serializations here.

@fantasai
Copy link
Collaborator

@Loirooriol
Copy link
Contributor

if an inline flow-root box is blockified, it becomes a block box (losing its flow-root nature).

I think blockifications should trigger becoming a formatting context to ensure that flow-root is not really lost (at used value time).

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

7 participants