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-break][css-display] box-decoration-break and multi-box inline elements #1706

Closed
Loirooriol opened this Issue Aug 9, 2017 · 12 comments

Comments

Projects
None yet
5 participants
@Loirooriol
Collaborator

Loirooriol commented Aug 9, 2017

CSS Break says that box-decoration-break controls what happens when a box has multiple fragments.

It does not say anything about an element which generates multiple boxes, each one with a single fragment. This can happen when an inline element is broken by a block-level descendant.

So my understanding is that if you have (jsfiddle)

span {
  background: linear-gradient(to right, green, yellow);
  border: 10px solid blue;
  padding: 10px;
  line-height: 5em;
}
<span>Lorem ipsum<div></div>Lorem ipsum</span>

then the element styles are assigned to each box independently (according to CSS Display), so each box has it's own border, padding and background, even if box-decoration-break is slice. However, no browser seems to do this:

image

Should this case be treated like when a box has multiple fragments, i.e. should all boxes share the same margin, border, padding and background? Should only some be shared? None?

@SelenIT

This comment has been minimized.

Show comment
Hide comment
@SelenIT

SelenIT Aug 9, 2017

Collaborator

I still consider "multi-box" inline elements created by block box intrusion contradicting the Priority of Constituencies principle. I see completely no reason for them to be any different from inline boxes fragmented between different page or column boxes, other than theoretical difficuilty to describe the the box tree in the first case. And I see no reasons for the author to expect them to render differently.

Are there really no other way to resolve the box tree problem in that case other than making inline element "multi-box"? Can't we, for example, consider two anonymous block boxes created by the block intrusion a single anonymous block box fragmented into two parts instead, with single, but fragmented, inline box inside?

Collaborator

SelenIT commented Aug 9, 2017

I still consider "multi-box" inline elements created by block box intrusion contradicting the Priority of Constituencies principle. I see completely no reason for them to be any different from inline boxes fragmented between different page or column boxes, other than theoretical difficuilty to describe the the box tree in the first case. And I see no reasons for the author to expect them to render differently.

Are there really no other way to resolve the box tree problem in that case other than making inline element "multi-box"? Can't we, for example, consider two anonymous block boxes created by the block intrusion a single anonymous block box fragmented into two parts instead, with single, but fragmented, inline box inside?

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol Aug 9, 2017

Collaborator

@SelenIT I don't disagree, saying that the inline element is broken into multiple boxes seems an ad-hoc solution which doesn't completely work. But I prefer the box tree to be a well-defined tree, and I don't see any great solution.

You propose that the anonymous blocks should be a single box, fragmented. And I guess there would be a single inline box which would be the child of the anonymous box. But then where do you place the block-level which splits the inline in the box tree? I guess it should be a sibling of the anonymous box, but should it be the previous or the following sibling? I guess it can't be the previous one, this could break the determination of the first formatted line of the parent. Not sure if there are problems if it's the following sibling.

Collaborator

Loirooriol commented Aug 9, 2017

@SelenIT I don't disagree, saying that the inline element is broken into multiple boxes seems an ad-hoc solution which doesn't completely work. But I prefer the box tree to be a well-defined tree, and I don't see any great solution.

You propose that the anonymous blocks should be a single box, fragmented. And I guess there would be a single inline box which would be the child of the anonymous box. But then where do you place the block-level which splits the inline in the box tree? I guess it should be a sibling of the anonymous box, but should it be the previous or the following sibling? I guess it can't be the previous one, this could break the determination of the first formatted line of the parent. Not sure if there are problems if it's the following sibling.

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Aug 15, 2017

Contributor

It does not say anything about an element which generates multiple boxes, each one with a single fragment. This can happen when an inline element is broken by a block-level descendant.

This is a case of a single box with multiple fragments. See https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level

Contributor

fantasai commented Aug 15, 2017

It does not say anything about an element which generates multiple boxes, each one with a single fragment. This can happen when an inline element is broken by a block-level descendant.

This is a case of a single box with multiple fragments. See https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol Aug 15, 2017

Collaborator

@fantasai Sorry but @tabatkins disagrees. It's not a single box with multiple fragments, the element generates multiple boxes instead. See #1477.

Collaborator

Loirooriol commented Aug 15, 2017

@fantasai Sorry but @tabatkins disagrees. It's not a single box with multiple fragments, the element generates multiple boxes instead. See #1477.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Aug 15, 2017

Member

Yes, this is very much not "a single box with multiple fragments", or at least, it's very unclear precisely what it is right now. We talk about it in terms of splitting into several boxes, with the block box descendant becoming a sibling box to the top-level inline box. For many purposes, it's indistinguishable from that; that is, the end effect of:

<inline>foo<block>bar</block>foo</inline>

is identical to the end effect of:

<inline>foo</inline><block>bar</block><inline>foo</inline>

Not for all purposes, certainly, but layout treats the two equivalently, for instance. (Unless the inline's container intervenes before splitting can happen and blockifies or inlinifies the element, of course.)

Member

tabatkins commented Aug 15, 2017

Yes, this is very much not "a single box with multiple fragments", or at least, it's very unclear precisely what it is right now. We talk about it in terms of splitting into several boxes, with the block box descendant becoming a sibling box to the top-level inline box. For many purposes, it's indistinguishable from that; that is, the end effect of:

<inline>foo<block>bar</block>foo</inline>

is identical to the end effect of:

<inline>foo</inline><block>bar</block><inline>foo</inline>

Not for all purposes, certainly, but layout treats the two equivalently, for instance. (Unless the inline's container intervenes before splitting can happen and blockifies or inlinifies the element, of course.)

@SelenIT

This comment has been minimized.

Show comment
Hide comment
@SelenIT

SelenIT Aug 17, 2017

Collaborator

but layout treats the two equivalently, for instance.

Sorry, but browsers seem to disagree (see a fork of @Loirooriol's example). The rendering effect, regarging borders, paddings etc, is clearly different.

Yes, CSS2.1 describes this difference (not expressible in CSS2.1 terms!) as a special case of two boxes rendering, but this was before the fragmentation concept, and visually the behavior of inline content in this situation looks rather indistinguishable from the fragmentation of inline content fragmented between fragments of a block box fragmented between two column or page boxes.

Also, the CSS2.1 uses the term "the block-level box contained in the inline box". Maybe, if the box is now a pre-rendering concept (according to your explanation in #1604), it would be better really to consider this situation as a three block boxes contained in the single inline box, and two inline box fragments divided between two of them?

Collaborator

SelenIT commented Aug 17, 2017

but layout treats the two equivalently, for instance.

Sorry, but browsers seem to disagree (see a fork of @Loirooriol's example). The rendering effect, regarging borders, paddings etc, is clearly different.

Yes, CSS2.1 describes this difference (not expressible in CSS2.1 terms!) as a special case of two boxes rendering, but this was before the fragmentation concept, and visually the behavior of inline content in this situation looks rather indistinguishable from the fragmentation of inline content fragmented between fragments of a block box fragmented between two column or page boxes.

Also, the CSS2.1 uses the term "the block-level box contained in the inline box". Maybe, if the box is now a pre-rendering concept (according to your explanation in #1604), it would be better really to consider this situation as a three block boxes contained in the single inline box, and two inline box fragments divided between two of them?

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol Aug 19, 2017

Collaborator

A proposal:

  • Invariant: the box tree respects the element tree parentage. That is, if E1 and E2 are elements such that E2 is a descendant of E1 (in the element tree) and both generate boxes, then all the boxes generated by E2 are descendants of (at least) the principal box generated by E1 (in the box tree).

  • Therefore, <main><span>Lorem ipsum<div></div>Lorem ipsum</span></main> initially produces this box tree:

    main: block box
      └ span: inline box
          └ div: block box
    
  • The definition of inline box is changed to

    An inline box is one that is inline-level, whose inline-level contents participate in its containing inline formatting context, and whose in-flow block-level contents participate in its nearest block formatting context ancestor.
    Note: an inline box is guaranteed to have at least one block formatting context ancestor.

    Of course this breaks the invariant "an in-flow non-root box participates in the nearest formatting context established by an ancestor box". But I don't think it's a big problem because inline formatting contexts are "weak" (like ruby ones, but those inlinify), so they can be the exception.

  • Then #1617 is approved and element-generated block containers never establish an inline formatting context. Instead, sequences of inline-level boxes generate an anonymous parent.

    main: block box, BFC or no FC
      └ anonymous: block box, IFC root
         └ span: inline box, no FC
             └ div: block box, no FC
    
  • And finally CSS Break says that a block box breaks all its immediate ancestors that are inline boxes or anonymous blocks. So the fragment "tree" becomes

    first&last fragment of main
      └ first fragment of anonymous
         └ first fragment of span
      └ first&last fragment of div
      └ last fragment of anonymous
         └ last fragment of span
    

    All the mess is moved into the fragment "tree", which I don't think it's a well-defined tree, so more handwaving shouldn't be a problem.

Collaborator

Loirooriol commented Aug 19, 2017

A proposal:

  • Invariant: the box tree respects the element tree parentage. That is, if E1 and E2 are elements such that E2 is a descendant of E1 (in the element tree) and both generate boxes, then all the boxes generated by E2 are descendants of (at least) the principal box generated by E1 (in the box tree).

  • Therefore, <main><span>Lorem ipsum<div></div>Lorem ipsum</span></main> initially produces this box tree:

    main: block box
      └ span: inline box
          └ div: block box
    
  • The definition of inline box is changed to

    An inline box is one that is inline-level, whose inline-level contents participate in its containing inline formatting context, and whose in-flow block-level contents participate in its nearest block formatting context ancestor.
    Note: an inline box is guaranteed to have at least one block formatting context ancestor.

    Of course this breaks the invariant "an in-flow non-root box participates in the nearest formatting context established by an ancestor box". But I don't think it's a big problem because inline formatting contexts are "weak" (like ruby ones, but those inlinify), so they can be the exception.

  • Then #1617 is approved and element-generated block containers never establish an inline formatting context. Instead, sequences of inline-level boxes generate an anonymous parent.

    main: block box, BFC or no FC
      └ anonymous: block box, IFC root
         └ span: inline box, no FC
             └ div: block box, no FC
    
  • And finally CSS Break says that a block box breaks all its immediate ancestors that are inline boxes or anonymous blocks. So the fragment "tree" becomes

    first&last fragment of main
      └ first fragment of anonymous
         └ first fragment of span
      └ first&last fragment of div
      └ last fragment of anonymous
         └ last fragment of span
    

    All the mess is moved into the fragment "tree", which I don't think it's a well-defined tree, so more handwaving shouldn't be a problem.

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Aug 20, 2018

Contributor

Minutes from the WG discussion on block-in-inline splits: the two parts of the inline are fragments of a single box. https://lists.w3.org/Archives/Public/www-style/2018May/0043.html

Contributor

fantasai commented Aug 20, 2018

Minutes from the WG discussion on block-in-inline splits: the two parts of the inline are fragments of a single box. https://lists.w3.org/Archives/Public/www-style/2018May/0043.html

@fantasai fantasai changed the title from [css-break] box-decoration-break and multi-box inline elements to [css-break][css-display] box-decoration-break and multi-box inline elements Aug 20, 2018

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Aug 20, 2018

Contributor

Tagging against display, since we might want to reference these effects from its Introduction, to clarify that they're considered cases of fragmentation.

Contributor

fantasai commented Aug 20, 2018

Tagging against display, since we might want to reference these effects from its Introduction, to clarify that they're considered cases of fragmentation.

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Sep 12, 2018

Contributor

Added cross-references about fragments being caused by bidi and X-in-Y splits to CSS Display and CSS Fragmentation: 7f6b964 a049017

Remaining question is, should we allow box-decoration-break to affect these cases? Currently it's a MUST for normal fragmentation, MAY for bidi. Propose to have MAY also for block-in-inline / spanner-in-block.

Contributor

fantasai commented Sep 12, 2018

Added cross-references about fragments being caused by bidi and X-in-Y splits to CSS Display and CSS Fragmentation: 7f6b964 a049017

Remaining question is, should we allow box-decoration-break to affect these cases? Currently it's a MUST for normal fragmentation, MAY for bidi. Propose to have MAY also for block-in-inline / spanner-in-block.

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Sep 12, 2018

Contributor

Patch (which could maybe use some wordsmithing):

diff --git a/css-break-3/Overview.bs b/css-break-3/Overview.bs
index f3cab08..a7748ed 100644
--- a/css-break-3/Overview.bs
+++ b/css-break-3/Overview.bs
@@ -1036,10 +1036,19 @@ Fragmented Borders and Backgrounds: the 'box-decoration-break' property</h3>
     on the left, the value ''slice'', on the right the value ''clone''.
   </div>
 
-  <p>UAs may also apply 'box-decoration-break' to control rendering
-  at bidi-imposed breaks, i.e. when bidi reordering causes an inline
-  to split into non-contiguous fragments. Otherwise such breaks are
-  always handled as ''slice''.
+  <p>UAs may also apply 'box-decoration-break'
+  to control rendering at bidi-imposed breaks--
+  i.e. when bidi reordering causes an inline to split into non-contiguous fragments--
+  and/or at display-type&ndash;imposed breaks--
+  i.e. when a higher-level <a>display type</a>
+  (such as a <a>block-level box</a> / <a href="https://www.w3.org/TR/css-multicol-1/#spanning-columns">column spanner</a>)
+  splits an incompatible ancestor
+  (such as an <a>inline box</a> / <a>block container</a>).
+  Otherwise such breaks are always handled as ''slice''.
+  See [[css-writing-modes-3#bidi-algo|Applying the Bidirectional Reorderign Algorithm]]
+  in [[css-writing-modes-3#text-direction|CSS Writing Modes]],
+  <a href="https://www.w3.org/TR/CSS2/visuren.html#box-gen">CSS2&sect;9.2 Block-level elements and block boxes</a>,
+  and <a href="https://www.w3.org/TR/css-multicol-1/#spanning-columns">CSS Multi-column Layout &sect;6 Spanning Columns</a>.
 
   <p class=note>
   For inline elements, which side of a fragment is considered the broken edge
Contributor

fantasai commented Sep 12, 2018

Patch (which could maybe use some wordsmithing):

diff --git a/css-break-3/Overview.bs b/css-break-3/Overview.bs
index f3cab08..a7748ed 100644
--- a/css-break-3/Overview.bs
+++ b/css-break-3/Overview.bs
@@ -1036,10 +1036,19 @@ Fragmented Borders and Backgrounds: the 'box-decoration-break' property</h3>
     on the left, the value ''slice'', on the right the value ''clone''.
   </div>
 
-  <p>UAs may also apply 'box-decoration-break' to control rendering
-  at bidi-imposed breaks, i.e. when bidi reordering causes an inline
-  to split into non-contiguous fragments. Otherwise such breaks are
-  always handled as ''slice''.
+  <p>UAs may also apply 'box-decoration-break'
+  to control rendering at bidi-imposed breaks--
+  i.e. when bidi reordering causes an inline to split into non-contiguous fragments--
+  and/or at display-type&ndash;imposed breaks--
+  i.e. when a higher-level <a>display type</a>
+  (such as a <a>block-level box</a> / <a href="https://www.w3.org/TR/css-multicol-1/#spanning-columns">column spanner</a>)
+  splits an incompatible ancestor
+  (such as an <a>inline box</a> / <a>block container</a>).
+  Otherwise such breaks are always handled as ''slice''.
+  See [[css-writing-modes-3#bidi-algo|Applying the Bidirectional Reorderign Algorithm]]
+  in [[css-writing-modes-3#text-direction|CSS Writing Modes]],
+  <a href="https://www.w3.org/TR/CSS2/visuren.html#box-gen">CSS2&sect;9.2 Block-level elements and block boxes</a>,
+  and <a href="https://www.w3.org/TR/css-multicol-1/#spanning-columns">CSS Multi-column Layout &sect;6 Spanning Columns</a>.
 
   <p class=note>
   For inline elements, which side of a fragment is considered the broken edge
@css-meeting-bot

This comment has been minimized.

Show comment
Hide comment
@css-meeting-bot

css-meeting-bot Sep 19, 2018

Member

The CSS Working Group just discussed box-decoration-break and multi-box inline elements.

The full IRC log of that discussion <gregwhitworth> Topic: box-decoration-break and multi-box inline elements
<astearns> github: https://github.com//issues/1706#issuecomment-420474809
<gregwhitworth> astearns: describes what is in the issue
<gregwhitworth> fantasai: do we want to allow box-decoration-break to close the fragments similiar to what would occur when there is a forced line break?
<gregwhitworth> astearns: it describes non-contiguous fragments
<gregwhitworth> fantasai: I could possibly make that a little bit clearer with regards to bidi
<gregwhitworth> fantasai: the two fragments may end up ajacent to each other, the way the inline happens to break
<gregwhitworth> fantasai: the rule for bidi, on an infinitely long line you end up with something in the middle of the inline box to split into two. The intruder are meant to be two seperate fragments even though they end up next to each other it provides us with the information we need
<gregwhitworth> fantasai: in that case if you did, box-decoration: clone you would end up with text in between them because the bidi algo
<gregwhitworth> fantasai: I think I can try to make it slightly clearer
<gregwhitworth> fantasai: the part about non-contiguous is an example - it's not exhaustive
<gregwhitworth> astearns: that's fair
<gregwhitworth> fantasai: I think the wording is ok
<gregwhitworth> dbaron: one about the bidi thing
<gregwhitworth> dbaron: where implementations would create a seperate fragment logically but they can never be seperate
<gregwhitworth> fantasai: or if you have an inline which has english text, a little bit, there is nothing that lets the user know there are multiple fragments
<chris> rrsagent, here
<RRSAgent> See https://www.w3.org/2018/09/19-css-irc#T16-21-06
<gregwhitworth> dbaron: what you're saying is that it's on a visual perspective of whether it has the capability of breaking
<gregwhitworth> dbaron: that seems complicated to implement
<gregwhitworth> fantasai: this is about where it's defined to have a fragmenetation break
<gregwhitworth> fantasai: from a rendering perspective, the user can't tell that it's doing that
<gregwhitworth> fantasai: the only case this should be known, is where there is text outside of the inline is intruding on the inline
<gregwhitworth> dbaron: I'm a little worried about.... <garbled>
<gregwhitworth> dbaron: this section has a lot of mays in it, we should have an issue for better definition
<gregwhitworth> fantasai: for sure
<gregwhitworth> dbaron: please open an issue
<gregwhitworth> fantasai: I can open one
<gregwhitworth> astearns: just open an issue for defining it better and leave the may out of this draft
<gregwhitworth> fantasai: we don't have any implementations so the may is there
<gregwhitworth> dbaron: if it's actually what you want implementations to do - then I would say that whether it's a should, with a may it's not clear it's what you want an implementor to do
<gregwhitworth> fantasai: ok, that's fair
<gregwhitworth> fantasai: how would the WG prefer, a may with a note - or a must
<gregwhitworth> astearns: I'm thinking a note that states that a future level will completely specify what occurs in this situation
<gregwhitworth> florian: I think that's what should is for
<gregwhitworth> florian: add a note
<gregwhitworth> dbaron: I support should as well
<gregwhitworth> Proposed Resolution: Take the patch substituting should for may
<florian> s/add a note/should implies the note that astearns described/
<gregwhitworth> astearns: objections?
<gregwhitworth> Resolved: Take the proposed patch
<astearns> resolved: use should in the patch
<gregwhitworth> ^ what astearns said
Member

css-meeting-bot commented Sep 19, 2018

The CSS Working Group just discussed box-decoration-break and multi-box inline elements.

The full IRC log of that discussion <gregwhitworth> Topic: box-decoration-break and multi-box inline elements
<astearns> github: https://github.com//issues/1706#issuecomment-420474809
<gregwhitworth> astearns: describes what is in the issue
<gregwhitworth> fantasai: do we want to allow box-decoration-break to close the fragments similiar to what would occur when there is a forced line break?
<gregwhitworth> astearns: it describes non-contiguous fragments
<gregwhitworth> fantasai: I could possibly make that a little bit clearer with regards to bidi
<gregwhitworth> fantasai: the two fragments may end up ajacent to each other, the way the inline happens to break
<gregwhitworth> fantasai: the rule for bidi, on an infinitely long line you end up with something in the middle of the inline box to split into two. The intruder are meant to be two seperate fragments even though they end up next to each other it provides us with the information we need
<gregwhitworth> fantasai: in that case if you did, box-decoration: clone you would end up with text in between them because the bidi algo
<gregwhitworth> fantasai: I think I can try to make it slightly clearer
<gregwhitworth> fantasai: the part about non-contiguous is an example - it's not exhaustive
<gregwhitworth> astearns: that's fair
<gregwhitworth> fantasai: I think the wording is ok
<gregwhitworth> dbaron: one about the bidi thing
<gregwhitworth> dbaron: where implementations would create a seperate fragment logically but they can never be seperate
<gregwhitworth> fantasai: or if you have an inline which has english text, a little bit, there is nothing that lets the user know there are multiple fragments
<chris> rrsagent, here
<RRSAgent> See https://www.w3.org/2018/09/19-css-irc#T16-21-06
<gregwhitworth> dbaron: what you're saying is that it's on a visual perspective of whether it has the capability of breaking
<gregwhitworth> dbaron: that seems complicated to implement
<gregwhitworth> fantasai: this is about where it's defined to have a fragmenetation break
<gregwhitworth> fantasai: from a rendering perspective, the user can't tell that it's doing that
<gregwhitworth> fantasai: the only case this should be known, is where there is text outside of the inline is intruding on the inline
<gregwhitworth> dbaron: I'm a little worried about.... <garbled>
<gregwhitworth> dbaron: this section has a lot of mays in it, we should have an issue for better definition
<gregwhitworth> fantasai: for sure
<gregwhitworth> dbaron: please open an issue
<gregwhitworth> fantasai: I can open one
<gregwhitworth> astearns: just open an issue for defining it better and leave the may out of this draft
<gregwhitworth> fantasai: we don't have any implementations so the may is there
<gregwhitworth> dbaron: if it's actually what you want implementations to do - then I would say that whether it's a should, with a may it's not clear it's what you want an implementor to do
<gregwhitworth> fantasai: ok, that's fair
<gregwhitworth> fantasai: how would the WG prefer, a may with a note - or a must
<gregwhitworth> astearns: I'm thinking a note that states that a future level will completely specify what occurs in this situation
<gregwhitworth> florian: I think that's what should is for
<gregwhitworth> florian: add a note
<gregwhitworth> dbaron: I support should as well
<gregwhitworth> Proposed Resolution: Take the patch substituting should for may
<florian> s/add a note/should implies the note that astearns described/
<gregwhitworth> astearns: objections?
<gregwhitworth> Resolved: Take the proposed patch
<astearns> resolved: use should in the patch
<gregwhitworth> ^ what astearns said
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment