- From: Andrew Fedoniouk <news@terrainformatica.com>
- Date: Fri, 27 Feb 2009 11:24:52 -0800
- To: David Hyatt <hyatt@apple.com>
- CC: Giovanni Campagna <scampa.giovanni@gmail.com>, Boris Zbarsky <bzbarsky@mit.edu>, www-style@w3.org
David Hyatt wrote: > On Feb 27, 2009, at 9:02 AM, Giovanni Campagna wrote: > >> 2009/2/27 Andrew Fedoniouk <news@terrainformatica.com>: >>> Boris Zbarsky wrote: >>>> >>>> Giovanni Campagna wrote: >>>>> >>>>> Can my text be the solution? >>>>> >>>>>> The resulting inline boxes should look exactly as they were >>>>>> contiguous >>>>>> in DOM, but owned by different line boxes (ie with a line break >>>>>> inside >>>>>> the inline box) >>>> >>>> I think so, yes. >>> >>> Could you explain then why these two spans should look >>> so "dramatically" different?: >>> >>> <!DOCTYPE html> >>> <html> >>> <head> >>> <style> >>> span div { border:1px solid; } >>> span { padding: 0 20px; background: green; border: 2px solid red } >>> </style> >>> </head> >>> <body> >>> <span>aaa<div>bbb</div></span><br/> >>> <span>aaa<div style="display:inline-block; >>> width:100%;">bbb</div></span> >>> </body> >>> </html> >> >> Because they are different: one creates an anonymous a block box, >> containing another anonymous block box, with a line box, with an >> inline box, connected to the span; sibling of the second block box, a >> new block is created, this time esplicitly, with line and inline >> boxes; lastly: a new anonymous block box, with line and inline boxes, >> the latter connected with the inline level element. That is, inline >> boxes created by the inline level element "<span>aaa</span>" are not >> ancestors of the <div> generated block boxes (this is not possible, >> only block, inline-block, table-cell, column and page boxes can >> contain other block boxes). They're not siblings either, because the >> sibling of a block box can only be a block box. >> Summing up boxes and associated elements: >> -block --> anonymous >> -block --> anonymous >> -line >> -inline --> <span>"aaa" >> -block --> <div> >> -line >> -inline -> "bbb" >> -block --> anonymous >> -line >> -inline --> "aaa"</span> >> >> As you see, properties set on <span> are completely unrelated to those >> on <div> (apart from inheritance), so the background and borders are >> not propagated to <div> >> >> The second example instead creates an anonymous block box (required by >> the first example, otherwise it would have used the <body> block box). >> Inside this box, initally a line box is created, that contains the >> root inline box, generated by <span>, that in turn contains generated >> by "aaa", then an inline-block for <div>, then another inline box for >> </span> (created because of padding and margin, see CSS21 9.4.2). >> This is therefore the initial box tree: >> -block --> anonymous >> -line >> -inline --> <span> >> -inline --> "aaa" >> -inline-block --> <div> >> -inline --> "" >> >> Unfortunately, the line box is wider than the block box, so it >> splitted into three line boxes as per normal line breaking rules. >> Although CSS2.1 is not very clear about this, I expect that the >> inline-block should be rendered as if it was an inline, replaced box, >> with trasparent background. >> Final box tree: >> -block --> anonymous >> -line >> -inline --> <span>"aaa" >> -line >> -inline-block --> <div> >> -line >> -inline --> ""</span> >> As you may see, in this example you only have one "block", and three >> line boxes owned by the same block. This means for example that if you >> set "line-height" on <body> (or a wrapping <div> that replaces the >> anonymous block box), also the inline-block will move. >> >> I know, this behaviour is far from intuitive, but as Boris said, this >> is what spec currently says and what browsers do. It's too late to >> change. > > I find this topic really interesting, since right now WebKit does the > first approach (creating "before" and "after" anonymous blocks and > splitting the inline flows into these before/after blocks), and it's > horrible to deal with. We call our implementation "continuations", > since the inline is effectively broken up into multiple objects. > > Pathologically constructed malformed Web sites create deep nestings of > inline flows. When this happens, the act of splitting becomes very > painful. It's O(n^2). > > https://bugs.webkit.org/show_bug.cgi?id=13430 > > Disconnecting the inlines also leads to weird rendering bugs. For > example try putting position:relative and a left/top offset on a span > that contains a div. In WebKit at least, the span and its > continuations will move, but the block won't. This happens because > the block is not actually a descendant of the span (or its > continuations) in the rendered object tree. > > I have been working on a new (more performant) implementation of > continuations in WebKit that would address both of the concerns I > raised above, and the approach I have been trying is kind of like the > second tree structure you've drawn above... i.e., create an > "anonymous" inline-block on a line by itself to hold the div. That > way the span doesn't have to split. I believe this approach could be > made to work, and pages that take 30+ seconds in other browsers load > in 3 seconds instead. The major difficulty with the inline-block > approach is you still have to run margin collapsing with contiguous > blocks (including other contiguous "anonymous" inline-blocks) if the > inline content before or after the block doesn't exist. > > I guess my point was we should be careful about being too explicit > about how the rendered tree has to be implemented, since a literal > interpretation of the spec leads to pretty undesirable performance > characteristics. > > dave > (hyatt@apple.com) > > > > The problem can be distilled to this: What exactly should happen if container element of display-model: inline-inside (e.g. span) that has a child of display:block (e.g. div)? I see only one reasonable solution in this case: display-model (that is hypothetical attribute that used to be in drafts at some point[1]) has an absolute priority in this case and so all its immediate children with display:block will have computed value of the display equal to 'inline-block'. This is pretty old problem actually. AFAIR Gecko and IE were using this way of treating display:blocks inside inlines from the very beginning. In general 'inline-block' value of the 'display' is superfluous. The only useful case for the 'inline-block' is when it is used for determination of actual value of "width:auto" of such block. In case of display:inline-block it gets resolved to width: max-intrinsic ((c) D. Baron) and in case of display:block inside spans it gets resolved to the width: 100%-of-nearest block-container-width. For the observer this means that pure <div> inside <span> shall take single line box as if that div was styled as {display:inline-block; width:100%}. [1] "The 'display', 'display-model' and 'display-role' properties" http://www.w3.org/TR/2002/WD-css3-box-20021024/#L706 -- Andrew Fedoniouk. http://terrainformatica.com
Received on Friday, 27 February 2009 19:25:39 UTC