Re: [css-logical-properties] the 'inline-{start,end}' values for 'float' and 'clear'

Sent from my iPad

> On Nov 13, 2015, at 9:29 AM, Johannes Wilm <johanneswilm@vivliostyle.com> wrote:
> 
> 
> 
>> On Fri, Nov 13, 2015 at 4:46 PM, Brad Kemper <brad.kemper@gmail.com> wrote:
>> 
>> 
>> 
>> 
>> 
>> Brad Kemper
>> On Nov 12, 2015, at 12:56 AM, Johannes Wilm <johanneswilm@vivliostyle.com> wrote:
>> 
>>> 
>>> 
>>>> On Thu, Nov 12, 2015 at 8:55 AM, Brad Kemper <brad.kemper@gmail.com> wrote:
>>>> Hopefully I won't be the only one to reply, but I wanted to clarify a few things.... 
>>>> 
>>>> 
>>>> 
>>>> Sent from my iPad
>>>> On Nov 11, 2015, at 10:09 AM, Johannes Wilm <johanneswilm@vivliostyle.com> wrote:
>>>> 
>>>>> 
>>>>> Hey again,
>>>>> I have looked a bit more at the different specs. And I have some questions to better understand the concerns Brad came with.
>>>>> 
>>>>> 
>>>>> On Exclusions vs. Visuren
>>>>> 
>>>>> Both the part about floats in CSS 2.1 Visuren [1] and the CSS Exclusion spec [2] have instructions exactly how to do the placement process of the float. As far as I can tell, the one in Visuren only works for floats that relate to subsequent content, whereas the exclusion one is more general for something that can be placed in some other part of the site.
>>>>> 
>>>>> Now if we want to float up, as far as I can tell, we can't really use the rules from Visuren, because we have to influence previous content.
>>>> 
>>>> The rules from Visuren don't have the feature for forcing the float to the top or bottom, but that doesn't mean it can't be added in a way that otherwise keeps everything else described there the same. 
>>> 
>>> As I read the rules, they talk about how subsequent content should behave. But this would not be enough, one would also have to describe how previous content behaves which in turn would affect the float itself, if one does not describe in what way it is exempt from the rules.
>> 
>> When it is at the top of the containing block, there is no previous content. 
>> 
>> Step 1: move it to the start start of the containing block. 
>> 
>> Step 2: left it be a left float or right float or none float (in the inline direction), to affect subsequent content. 
>> 
>> Step 3: There is no step three. 
>> 
>> For putting it at the bottom it would just make the containing block taller or cause overflow if it couldn't. For fragmenting containers it's a little trickier, because it needs to be placed just high enough to fit. The UA would probably have to compose bottom floats offscreen first to determine fit, in order to know what line to start them on. And they might need a nudge down of less than a line height, in order for their bottom margin to align with the bottom of the page/column/region. 
> 
> 
> The Visuren document mentions 9 rules to determine the placement of a float [4]. 
> The Exclusion spec mentions 4 steps + 2 rules to figure out how the flowing of text around the exclusion works [5].
> The Page Float draft spec mentions about 8 steps + 2 rules to place the float [6].
> 
> I think we need something at least of this type of level of specificity if it is to work as alternative proposal.
> 
> Now I would just extend the page float model to also work for block floats. 
>  
>> 
>> 
>>>> The basic thing I suggested was to move the left/right/none float to the beginning of the first line box of the containing block when a new property (aka 'block-start', 'top', etc.) of 'float' told it to. If something else had already been put there by the same value, then you'd put it right after it. But the left and right floating would still work exactly the same. 
>>>> 
>>>> This can even be simulated with JavaScript, or by moving a float around using the Inspector in your browser. Once you move it to being the first thing in the box, it is still a left float or right float, in exactly the way described in Visuren. Or if the inline direction part was 'none', it still would be after moving it to the block start.
>>> 
>>> You seem to be suggesting top/down movement within one container element.
>> 
>> Yes, that would be the default containing block for property values that moved the floats in the block direction. 
>> 
>>> So that is only for that case, not for page floats that locate over a series of fragments, correct? 
>> 
>> Not correct. I thought I described a property called 'float-to' that would combine the general effects of 'float-reference' and 'float-defer'. It's possible I haven't sent that yet. 
> 
> 
> In that, case I think you need to write instructions that cover the area of the 4 steps + 2 rules in the Exclusion spec and 8 steps and 2 rules from the page float spec. That does not necessarily mean you have to write 12 steps + 4 rules, some things may be combinable, but we will need the preceise instructions on how to place things. Not just a vague description saying we "nodge" the float this or that way.

You're right in that of course it would need to be detailed out in a float spec, which I don't have a lot of time to do right this moment. But as long as you put exclusion floats into other properties instead of 'float', e.g. 'wrap-float', 'wrap-float-reference', etc., or maybe 'wrap-stack', 'wrap-stack-reference', etc., and therefore not confuse the issue of how floats and exclusions are two different animals, then this would also keep open the future possibility of two dimensional control of real floats, along the lines of what I've been describing. 

> 
>> It would be a two part value, with the second value optional. The first part would allow you to choose between containing-block, column, page, and region. It would move it to the first ancestor that matches. This is what I originally imagined 'float-reference' would do. 
>> 
>> The second part would be a number or 'last', to move it to a different subsequent column, page, or region of the same chain. 
>> 
>>> What about a recipe for the stacking of such floats? 
>> 
>> I think I already suggested a property and how it would work. 
>> 
>>>>> Then there is the section of the CSS Exclusion spec that talks about differences between exclusions and floats [3]:
>>>>> 
>>>>> "
>>>>> scope. While floats apply to content that follows in the document, exclusions apply to the  content in their containing block.
>>>>> positioning. Floats are part of the inline flow and float on the line box. Authors can control how the floats move on the line box, to the right or to the left. By contrast, exclusions can be positioned using any positioning scheme such as grid layout ([CSS3-GRID-LAYOUT]), flexible box ([CSS3-FLEXBOX]) or any other CSS positioning scheme.
>>>>> separation of concerns. Making an element a float determines both its positioning scheme and its effect on inline content. Making an element an exclusion only determines its impact on inline content and does not impose constraints on its positioning method.
>>>>> "
>>>>> 
>>>>> The first of those three would not apply to page floats and top floats anyway.
>>>> 
>>>> Doesn't it? Can't a tall float starting on the first line  (or exclusion positioned at the top) be sticking out of the bottom of a short (fixed height) column, and affecting (or not) the content below it?
>>> 
>>> 
>>> Two parts here:
>>> 
>>> 1. Do the mentioned restrictions for floats apply ("apply to content that follows in the document")?
>> 
>> For what I've been describing? Yes. 
> 
> As far as I read your suggestion, that is not the case. If you have a top-float in the third paragraph of a container, and the float floats to the top of that container, then you are affected the first two paragraphs, that came before the float in document order.

The change to the rule is to treat the float as though it is the first thing in the box, when it has 'float: start start' (or start:top in ltr ttb languages). It then would apply to contents that follow it in the new order. We can adjust the language a little if we need to, but it is not that complicated. We would need to adjust the language anyway to accommodate logical key words in the inline direction. 

The major thing about "apply to content that follows in the document" that makes it different from exclusions is that it even applies to conte t outside the containing block. So if it was overflowing the block, it could cause text in the next block to wrap too.

>>> No, because it could also affect content that comes before it.
>> 
>> Incorrect. It is moved first, then affects only the content that comes after it in its new position. It also affects content in blocks that follow after its own containing block, which exclusions don't. 
> 
> What do you mean by "moved first"? 
>  
> Are you saying that you will have a step 0, which is to happen before any other part of layouting, in which you move all top floats in the layouting order so that they appear as if they were the first childNodes of a given block element, and all the bottom floats as if they were the last childNodes of that block element? And then you want the exception mentioned in the exclusion doc only apply from step 1, because your step 0 will happen before anything else?

Yes, more or less. Once you see that 'top' or 'start' in the block direction, 

> I think that should work for top floats, but for bottom floats, that are also floating right/left, this would not work, AFAICT. The bottom floats would be placed after all other content and therefore the text would not flow into the cracks between the bottom floats.
> 
> So this is a nut to crack -- if you want to propose an alternative.

I think I have the basics described in another email, but that part needs more work to describe. That one would be moving the floats to a different spot before wrapping also. If they are moved to a distance from the bottom that is equal to to their height, then the text can flow down around them from that. I know this would need to be described more precisely, but the basics are still based on floats as we know them.

>>> 2. Do the mentioned restrictions for exclusions apply ("apply to the  content in their containing block")?
>>> 
>>> Yes, at least according to the current spec.
>> 
>> Only to content in the same containing block. Floats can affect content outside the containing block. 
> 
> Can you explain in what sense you mean here?

See the illustration in Visuren that follows the text, "Here is another illustration, showing what happens when a float overlaps borders of elements in the normal flow" (shortly before 9.5.1). The red boxes are the containing blocks. 

> And in what sense this should apply to page floats as they are currently defined?

Page floats as they are currently defined are exclusions. It is fine for exclusions to be different from floats, as long as they are not using the 'float' property or confusing one for the other. If you have a property that positions exclusions, which contain a completely separate set of rules for wrapping than floats do, then it shouldn't be a value of the 'float' property, and it shouldn't have other properties that by their name seem to be associated with 'float'. 

>  
>> 
>>> Non-overlapping is only guaranteed for other floats with the same float reference and the bfc has the same dimensions as the float reference. This means one cannot simply make a column float overlap the next column by setting the width to 200% or some such thing. The point of this is mainly to cut down on the complexity needed.
>> 
>> I don't think a float can cross columns that way either. They get clipped. They can flow from one column to the next in the block direction, if the column height is restricted (they basically get sliced in two). 
> 
> Are you talking about the inline floats? The page floats should be defined in a way that they should not get clipped across fragments like that.

Yes. We'd still need something to allow a float to cross columns. It doesn't seem like a hard nut to crack. A float protruding into a second column should have text flow around it in the same as as though it started in that column. It just doesn't do that today, so it would need another keyword value added to 'float' to allow it to do so.

>>>>> The remaining two issues just seem to basically explain how exclusions work and that they don't determine positioning. 
>>>> 
>>>> There are other significant differences too. For instance, z-index changes the wrapping in exclusions. This can affect page floats as exclusions too, since negative margins can still cause them to overlap each other. 
>>> 
>>> negative margins... ok, possibly that would be doable. Either we forbid negative margins for placement calculation, or we keep them. If we keep them, we have the advantage of already having a pre-defined behavior.
>> 
>> Real floats can have negative margins. Either way, your results with exclusions, even in the inline direction, are going to be noticeably different than traditional floats.  
>> 
>> I don't think you should restrict against negative margins. It's just a different model than floats, though, and should be recognized as such. 
> 
> The page floats should never affect content outside of their float reference. That is the way the spec is currently written and that is the behavior that is requested for our purposes at least.

Yeah, that's a key thing that makes them different from floats. I'm not sure what that has to do with supporting negative margins in general.

>>>>> Given that the point of the page float spec would be to describe positioning and leave the description of how that influences text flow of the content behind it to the exclusion spec, it doesn't seem like this would make it incompatible either.
>>>>> 
>>>>> 
>>>>> So my question now is: What difference would it make if we would try to define the same page floats as we have them now without pointing to the CSS Exclusion spec? Would we not have to end up having to describe much of the same of how content flows around it as is now in the CSS Exclusion spec?
>>>> 
>>>> In my view, no, not if we went with something like I suggested (where the vertical component just changed the line box, but kept inline floating the same). We would have to describe the floats-clearing-other-floats-only behavior that I suggested for a separate property, which would give us vertical columns of single left floats or right floats. Even this one though, is basically just like changing the order of the floats in the document a little prior to applying the rules of Visuren. Conceptually it is not too different from 'order' in flexbox. 
>>> 
>>> Ok, my udnerstanding is that your proposals are meant for top/down single box floats, not page floats, right?
>> 
>> That depends on how one defines page floats. It's using the float property to move an item to the block start or end) of a containing-block, column, page, and region, where it can then float or not in the inline direction. 
> 
> If you want to define page floats without using the exclusion spec, then I think in order to be able to evaluate such an alternative proposal, we need those instructions.

Sure, but you don't have to wait for that. Since you obviously prefer an exclusion positioning scheme that is superficially similar to existing floats, then just go ahead and continue to spec that, but using properties that aren't called 'float' or start with 'float-'. They can can co-exist with 'float', if they are in separate properties. I've provided an outline of how inline floats can be usefully positioned in the block direction, but I fully support your effort to have a float-like positioning scheme for exclusions too, as long as they are kept separate. 

This would also allow you to have inline-positioned exclusions, which could be a nice alternative to regular inline floats. Suppose your property was called 'wrap-stack', and you had a picture with a class of "floater" in the first line of a paragraph. You could have this:

.floater {
    wrap-stack-reference: column;
    wrap-stack: left none;
    margin-top: -3em;
    height: 6em;
}

This would cause it to keep its natural vertical position in the flow of the column and paragraph (because 'none' doesn't force it to top or bottom), aside from moving it up 3em via margin-top. But because it's an exclusion of the column, the paragraph above it also can wrap around it. Deferring it would put it in the top left corner of the thing it was deferred to. 

>>>> Moving left/right floats to the bottom is a maybe little trickier, because after you move several things to the same line box, their margin boxes will be aligned along the top, and more line boxes could theoretically be created under them, but I think this too could be spec'ed in a useful but simple way that didn't change what it means to be a left/right float, as described in Visuren. 
>>>> 
>>>> For the exclusions version you've been working on, I don't think you'd have to repeat a lot of what is in the Exclusions spec. Once you say that the "floats" are actually exclusions, and that they follow all the rules of the Exclusions spec, then basically you are creating syntax for positioning things. I don't think you'd have to redefine anything that is in that spec already. It already avoids talking about where to put the exclusions. 
>>> 
>>> Exactly. That was the point of referring to the exclusion spec. Just keep it to placement.
>>>  
>>>> 
>>>>> On inline-start vs. start
>>>>> 
>>>>> I was thinking: One solution that could work with all the models would be if "start" and "end" simple referred to the inline directions, and one would still have to use "block-start" and "block-end" for the block directions. Maybe even have "start" and "inline-start".
>>>>> 
>>>>> Or would that break with the general naming scheme?
>>>> 
>>>> I think it is inconsistent with the general strategy of how we use these in other things, but I'll let others speak to that. 
>>>> 
>>>>> On logical directions
>>>>> 
>>>>> 
>>>>> I worked some on this, but had input from Shinyu and Elika, and our internal review at Vivliostyle made us think we are correct with the current formulation (which also seems to be in line with what Elika and Florian have said on the mailing list). Does anyone disagree with the current formulation? And if yes, what do you think it should say instead?
>>>> 
>>>> Just this:
>>>> 
>>>> If one value page floats were expandable into two values (as I believe they should), then 'start start' is better than 'inline-start block-start'. 
>>> 
>>> 
>>> To me it would seem that if we extend the current algorithm for placement, the easiest would be to add a secondary direction that is applied only after the first axis placement has taken place already. "inline-start" currently already means "inline-start block-start" and "block-start" means "block-start inline-start" where the second one is the secondary direction. The important thing is that "block-start inline-start" and "inline-start block-start" do not mean the same thing.
>> 
>> Typically, the horizontal direction comes first, and the vertical one second, when the values represent 2d axes. Given the western-centric preference in CSS (for initial values, etc), this would translate to inline direction first and block direction second. 
> 
> 
> Well, but we need to be able to stack in both directions.

Ah, I think I see the problem. 'Right top' puts it in the top right corner,  but doesn't say where to put the next 'right top' float. Underneath, or to the left? Is this the issue? I think word order is too subtle to use for that, and is an anti-pattern. You instead need another value, either to add as a third part ('wrap-stack: right top inline', if 'wrap-stack' is the property name for creating float-like positioned exclusions) or in a separate property (wrap-stack-direction: inline).

>> We don't typically change what each position represents to indicate order of execution. That would be very unusual and surprising. And writing four words instead of one or two would be author-hostile. 
>> 
>> With my scheme, you could still write 'float: left' and it would mean the same as 'float: left none'. In the same vein, 'float: top' would mean the same as 'float: none top'. This is consistent with other CSS constructions, and the rules for the other values fall out from there. 'Float:start' would be the same as 'float: start none' (floating inline only, which I expect would still get more use than block-direction floats). 
> 
> With what you have proposed so far:
> 
> We lose the information about stacking direction, which is vital for our purposes.

I had a property for that, and a description of how it worked. See the "like clear" thing described towards the end of this email.

> I wonder what exactly the use case is for having an easier way of doing "float: none top" differentiating it from "float: left top"? To me it does not seem intuitive that one of them left the text flow to the right of it while the other one doesn't, and I'm not sure why we would have a way to have the float at the top with no content to the right of it and not the equivalent to have it in the upper right corner.

'Margin-left:0' would put it in the right corner. 'Margin-left:0; Margin-right:0' would horizontally center it.  If it was 'width:auto', it would stretch all the way across. 

'None' is a valid inline direction value of inline floats. 'top' (in Western languages) takes it out of its original line box, and moves it to the inline start of the top line box, as I have described many times now. That means it no longer has its original horizontal position. It's on the left, not inline floating. 'none' has always meant not floating inline, and that's what it would mean in this position. I am giving it the block display effect of floats however.

> The current proposal allows for:
> 
> "float: block-start" which means "block-start" as the primary direction and "inline-start" as the secondary direction.

"Secondary direction" is a confusing term. It makes me wonder if I understand what you mean. Is it the axis that other floats of the same value are stacked along?

> If we add 2D as I proposed, it would also allow us to float in the other top corner:
> 
> "float: block-start inline-end".

If the first value was always horizontal or inline direction, and the second value was always vertical or block direction, then 'end start' would put it in that same corner.

>>>> And in the case that page floats were created via a separate property, instead of just a value of 'float' (as I feel they should be), then even if we don't yet add a new vertical (or bock direction) movement value to 'float' itself, we should have 'start' and 'end' values for the inline direction, and that should be added to an edit of the existing float spec language of Visuren. Then if we ever added a block direction to 'float' itself, it could be start, end, top, or bottom, to go into the second position of the value. A single start or stop would indicate inline direction only, just as left and right do now.
>>>> 
>>>>> On the name of the spec
>>>>> 
>>>>> I am fine with changing the name. Or keeping it. I would in general be in favor of describing both inline floats and page floats in the same spec, because they both use the same properties, but I don't have a very strong opinion on this. But besides Brad
>>>> 
>>>> Sorry, I just want to be clear. I don't feel strongly about the name of the spec itself, or if there is one spec or two specs or which ones appear together. What I do feel strongly about is that the property itself should not be 'float' if it works close to what is described. I don't think 'float:left' should ever change to a completely different alternative model of wrapping text and positioning, due to the presence of another property like 'float-reference'. When it does that, almost everything Visuren says about floats no longer applies, and is replaced by exclusions and the text that you have for placement and collision avoidance. 
>>> 
>>> but having "float: top" will already break the placement model mentioned in Visuren because it affects previous content, right?
>> 
>> Nope. Just one step to move it to the start of the first line box, then everything else in the model remains the same. The only things we are adding is that one step at the very beginning of the model processing. I keep saying this...
> 
> see above.

See above.  

>>>> I have suggested 'wrap-float' as an alternative property name that leaves 'float' alone, if you want to continue with an exclusion-based version of float-like positioning, in two dimensions. It's a little weird still, since floats wrap too, but exclusion properties all start with 'wrap-'. Maybe 'wrap-stack' would be better, since the new spec describes how to stack exclusions' margin boxes against each other vertically and horizontally. 
>>>> 
>>>> By the way, we should also change the term "page float" regardless. It isn't just pages anymore. 
>>> 
>>> "fragmentation floats"?
>> 
>> Yeah, maybe. 
>> 
>>> We could have three types of floats in that spec:
>>> 
>>> 1. inline floats (behave as usual)
>>> 
>>> 2. fragmentation floats (behave similar to what we currently call "page floats", with adjustments)
>>> 
>>> 3. block floats (have many of the same features as fragmentation floats, but cannot be deferred to subsequent containers, and "clear: top/bottom" may also have a different meaning or no meaning).
>> 
>> Just two:
>> 
>> 1. inline floats (behave as usual, but can be moved to top or bottom first). A new property is also added for vertical floating:  Prevents two same-value floats from being next to each other on a line, so second one moves down to a new line (like clearing), but still letting other inline content to flow around both. This is still just a "move vertically, then inline float as normal" kind of thing). 
>> 
>> 2. fragmentation floats (behave similar to what we currently call "page floats", with adjustments). Might need to have 'wrap-clear' or something to avoid conflict with similar vertical clearing of regular floats. Uses 'wrap-float' property and 'wrap-*' for other related properties, instead of 'float' and 'float-*'. 
> 
> 
> So you want to add vertical clearing to inline floats? How would that work?

If the float was in a chain of columns, pages, or regions, whichever was inner-most, 'clear: top' would move remaining top floats to the next of that chain, to the beginning of its first line box. Then it would do its inline floating there. 

Oh, but you are asking about the thing I said was "like clearing"? I meant similar to regular 'clear:left|right', in that it would move down below the previous float. But not exactly like full clearing, because other inline content (including floats that didn't have that property value) would still flow around both. It would be as if the second float had started on a lower line beneath the first float, and stayed there.

I think I described this in an email I never finished nor sent. This would probably cause the most changes to Visuren, but it is still conceptually not far from what's there. 

>> But yes, this is the way I see it. And if you want to do #2 first, I don't mind. 
>> 
>>> And then if I understand your proposal right, you would not want to refer to exclusions for "block floats" but are ok with them being used for "fragmentation floats"?
>> 
>> Yes, unless a better name is found. 
> 
> Ok, I think I now really understand what you are proposing so far. Thanks for that! If you can define the text flow and placement recipe, then I think it could turn into an alternative proposal.
>>>  
>>>> 
>>>>> and myself, what do other people think?
>>>>> 
>>>>> 
>>>>> [1] http://www.w3.org/TR/CSS21/visuren.html#floats
>>>>> [2] http://www.w3.org/TR/css3-exclusions/#exclusions-processing-model
>>>>> [3] http://www.w3.org/TR/css3-exclusions/#floats-and-exclusions-differences
> [4] http://www.w3.org/TR/CSS21/visuren.html#float-position
> [5] http://www.w3.org/TR/css3-exclusions/#exclusions-processing-model
> [6] https://drafts.csswg.org/css-page-floats/#page-float-placement

Received on Saturday, 14 November 2015 07:17:50 UTC