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

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

Comments

@Loirooriol
Copy link
Contributor

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
Copy link
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
Copy link
Contributor Author

@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
Copy link
Collaborator

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
Copy link
Contributor Author

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

@tabatkins
Copy link
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.)

@SelenIT
Copy link
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
Copy link
Contributor Author

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 [css-display][css-inline] Block containers should never establish an inline formatting context #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
Copy link
Collaborator

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 added the css-display-3 Current Work label Aug 20, 2018
@fantasai fantasai changed the title [css-break] box-decoration-break and multi-box inline elements [css-break][css-display] box-decoration-break and multi-box inline elements Aug 20, 2018
@fantasai
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
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

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