Re: [CSS3] Flexible Flow Module, proposal.

2009/4/12 Andrew Fedoniouk <news@terrainformatica.com>:
> Giovanni Campagna wrote:
>>
>> 2009/4/11 Andrew Fedoniouk <news@terrainformatica.com>:
>>>
>>> Giovanni Campagna wrote:
>>>>
>>>> I don't like this proposal, because:
>>>>
>>> Seems like you are trying to compare XUL flex system with
>>> the 'flow' and flexes of our proposal.
>>>
>>> XUL flex system is probably good for the XUL but attempt
>>> to marry it "as is" with the CSS is too straightforward in my opinion.
>>>
>>> By the way which one of these:
>>> http://damowmow.com/temp/csswg/flexbox.html
>>> http://xulplanet.com/ndeakin/xul/specs/flexbox.html
>>> defines the subject?
>>
>> I don't know which one the CSSWG adopted as draft, but I know:
>> - that something along the XUL model is in the charted (see Current Work)
>> - that the XUL box properties were in the old draft of Advanced Layout
>>
>>> In any case I think that having 8 attributes to define all this is too
>>> much. Almost each attribute in mentioned documents is interacting
>>> with the rest of CSS. That creates pretty complex graph of dependencies.
>>>
>>> As an example, what exactly is this:
>>>
>>> div {
>>>  box-flex:1;
>>>  width:100px;
>>>  height:100px;
>>> }
>>>
>>> ? What dimensions the block will have? What if I want it to flex
>>> in horizontal direction only? And so on.
>>
>> It depends on its parent. If its parent has a display of anything but
>> "box" / "inline-box" (or "flow", or "display-model"), its height and
>> width are computed as always (box-flex doesn't apply), if its parent
>> has a display (-model) of "box", its dimensions are computed with the
>> XUL box model, considering the intrinsic 100px x 100px dimensions.
>> This means that if there are no siblings and the width / height of
>> parent is "auto", the <div> is not streched, else it is streched to
>> fit the whole box (because box-flex is different than "0").
>> Only one of "width" / "heigth" is changed (the Used Value, not the
>> Computed), which one depends on the orientation of the parent
>> ("box-orient"). If there are siblings, the box will be streched in a
>> way that
>> (new_width - intrinsic_width) : box-flex = (new_width_sibling -
>> intrinsic_width_sibling) : box-flex_sibling
>> (assuming that both box-flex are different than "0")
>
> In other words width or height is simply ignored when box-flex > 0.
> And I suspect that the same will happen with min/max-width/height too.
>
> That creates indeed completely different box model that is far
> from CSS box model.
>
> It is also not clear what exactly is flexible, border box or
> content box of the element?

I personally think width / heigth (which means content-box or
border-box according to box-sizing)

> What to do if I only need to flex only margins as here:
> http://www.terrainformatica.com/w3/flex-layout/images/flex-springs.png
> to align the element with respect of its and its siblings intrinsic
> dimensions?
>
> In any case I do not thank that anyone will want to
> change CSS box model if there is an alternative that does not
> require such change.

I don't know...

>>
>>> In any case the 'flow' and flex length units solve three
>>> problems:
>>> 1) block alignment, horizontal and vertical (e.g. margin:1*, padding:1*);
>>> 2) introduces extensible list of various layout managers;
>>> 3) adds flexes.
>>>
>>> And XUL flex system you refer to seems like is aimed for latter two only.
>>
>> Did you forget box-pack and box-align?
>>
>>>> 1) What you call flows are actually XUL flexes, and thus should be
>>>> handled with the XUL box model.
>>>
>>> What exactly is "XUL box model" and how it is related to "CSS box model"?
>>>
>>>> Many of those properties are already implemented in Mozilla (with
>>>> -moz- prefix). You can find them at
>>>> <https://developer.mozilla.org/en/CSS_Reference/Mozilla_Extensions>
>>>> and you can find a proposal for the Flexible Box at
>>>> <http://damowmow.com/temp/csswg/flexbox.html>.
>>>
>>> Seems like each of UAs have its own unique set of features for many
>>> reasons. That does not imply that they should go to the common set.
>>> If FF is using XUL based chrome then it is probably makes sense to
>>> wrap XUL flex model into something CSS-ish.
>>
>> But David Hyatt noticed that those properties are also in WebKit. So,
>> if we need a new feature, it probably makes sense to reuse what exists
>> now (and maybe someone already uses)
>
> I haven't seen that anyone from professional designers even considering
> XUL flex model as an viable alternative to CSS box model.

And? How many people did you talk to?
(and consider that IE not implementing a feature is a very good reason
not to use it)

> I think that XUL by itself can
> benefit from adopting proposed flow and flex units.
>
> Flexible Flow Module introduces just two entities: the 'flow' attribute
> and flex units but it is functional *superset* of XUL flex model.
>
> I mean that XUL flex DOM attributes can be mapped to the 'flow' and flex
> units without any limitations.

Ok. But if we can do that without forgetting existing and implemented
properties, everybody will benefit.

>>
>>>> I'm sure that a more recent version of that is available as
>>>> member-only, since the Flexible Box Model is referenced in the Current
>>>> Work page for CSSWG.
>>>> (It would be great if the draft could be moved at the public cvs)
>>>>
>>>> 2) * units don't tokenize as DIMENSION, but rather as NUMBER followed
>>>> by DELIM. Use <fraction> and fr units instead (see Values and Units)
>>>> [CSS3SYNTAX] [CSS3VALUES]
>>>
>>> '*' units are already used in the CSS Grid module and CSS Template
>>> Layout..
>>> http://www.w3.org/TR/css3-layout/
>>> http://www.w3.org/TR/css3-grid/#lsquo
>>>
>>> Seems like many people agreed that 'width:1*' or in short form
>>> just 'width:*' means the same thing. They are also known in html
>>> as relative units and widely used in this form (at least in <frameset>)
>>> so I think it makes sense to keep them that way as web developers are
>>> already familiar with the notation.

They cannot be used anymore in conforming HTML(5) documents.

>> This doesn't mean that they should used, because they create problems
>> with tokenization and because alternatives are already present in CSS.
>> Do you want to have two units (* and fr) for the same purpose?
>
> I am not aware of any problems with tokenization of flex units.
>
> In the same way as lexical scanner can recognize '2%' it will also
> recognize '2*'. Not a problem at all.
>
> Consider this:
> http://www.w3.org/TR/CSS21/grammar.html#scanner
>
> {num}{E}{M}             {return EMS;}
> {num}{E}{X}             {return EXS;}
> ...
> {num}{H}{Z}             {return FREQ;}
> {num}{K}{H}{Z}          {return FREQ;}
> {num}{ident}            {return DIMENSION;}
>
> {num}%                  {return PERCENTAGE;}
> {num}*                  {return FLEX;}
> {num}                   {return NUMBER;}
>
> I have added this line above:
> {num}*                  {return FLEX;}
>
> And it does not conflict with anything in CSS grammar.
>

That is the second grammar. I meant the core grammar, at
<http://www.w3.org/TR/CSS21/syndata.html#tokenization> and
<http://www.w3.org/TR/css3-syntax/#tokenization>, and the core grammar
cannot be changed.

>>
>>>> 3) Combining percentages and lengths with calc() makes flexible units
>>>> mostly useless. For example, if width:50%, margin-left:2* (2fr) with
>>>> margin-right:1* (1fr) is equivalent to margin-left:33,33%
>>>> margin-right:16,67%. If width was 500px, you could write:
>>>> margin-left:calc((100% - 500px) * 0.66); and margin-rigth:calc((100% -
>>>> 500px) * 0.33);
>>>> This includes also the case where padding and borders are present.
>>>
>>> Sorry but
>>> margin-right:1* is not even close to margin-right:16,67%
>>>
>>> margin-right:1* defines how free space is distributed *after*
>>> computation of all required dimensions including percents.
>>>
>>> Values given in '*' units do not change intrinsic min/max dimensions
>>> of elements. margin-right:1* means pretty much this: "move element
>>> to the left as much as possible". Compare it with this
>>> "make right margin of the element of 16,67% of width of its
>>> container. No matter what rest of dimensions are".
>>>
>>> I thought that was clear. Seems like I need to put more wording
>>> about it.
>>
>> margin-right:1* on its own is margin-right:auto;
>>
>> but I meant
>>
>> margin-right:1*;
>> margin-left:2*;
>> width:50%
>>
>> / equals to /
>>
>> margin-right:16,67%;
>> margin-left:33,33%;
>> width:50%;
>
> You have missed one point. Flowed elements with default
> value of the 'overflow' (visible) cannot have
> width less than their intrinsic min width set. Flowed elements
> behave as table cells in this respect - they never overflow
> (if they have overflow:visible)
>
>
> See: http://www.terrainformatica.com/w3/flex-layout/flex-layout.htm
> Chapter #2.
>
> So this:
>
>  margin-right:1*;
>  margin-left:2*;
>  width:50%
>
> is in fact:
>
>  margin-right:1*;
>  margin-left:2*;
>  width:50%;
>  min-width:min-intrinsic;
>
> And this case is in principle not reproducible by the calc().

I don't like this (boxes should wrap or overflow), but it is anyway a feature.

>>
>> Because width must not be auto in order to introduce flexible margins,
>> with some mathematics you can get it away without flex units (I hope
>> that width:auto will remain as "margin-box  == parent's width")
>
> Flex units are implicitly used in <table> layout in HTML.
> So far <table> layout is not reproducible by CSS means. Even
> with display:table and friends. Flex as an entity is what that make
> <table> impossible to be defined in CSS. Our proposal makes this
> possible - you will have layout mechanism that is even more powerful
> than tables - it provides more layout options.

What in <table>s is not reproducible in CSS, with the automatic table layout?

> And all this by just using two additional entities.
>
>>
>>>> 4 The property for deciding how an element lays out its children is
>>>> "display-model". We don't need a new "flow" property for
>>>> that.[CSS3BOX]
>>>
>>> We already sang "Sic transit gloria mundi..." to the 'display-model'.
>>> It was integrated with the 'display' long time ago.
>>>
>>> I too think that that was wrong but we are here already.
>>
>> The problem is...
>> "Flow" is exactly equal to "display-model". The difference? Probably
>> just the name.
>
> As a name 'flow' is better as it defines more precisely what this attribute
> is for. Let 'display' be 'display' as it is now - it specifies requirements
> of the element to its container. E.g. by defining display:inline the element
> is asking to place itself in text container.
>
>
>> You wanted to introduce "flow: table". What is the difference with
>> "display-model:table"?
>
> Table can be display:inline-block and and can be display:block
> as any other block element. Table per se is a way of laying out its
> children.

That is "display-model": a way of laying out children. And that is
"display-role": how the element is used inside its parent.
Tables can have any value of "display-role" (block, inline, card,
table-cell, run-in, compact, table-caption...).
Compare

-- my proposal --
role => "display-role"
layout algorithm => "display-model"
"display" => shorthand
-- your proposal --
role => "display"
layout algorithm => "flow"

Advantages of my proposal: you reuse "display" as a shorthand, so
you're still backward compatible with CSS using "display:table" (that
becomes "display-model:table; display-role:block"). If "display" also
sets "flow" for some values, I will accept it (although I don't like
the name, I'd rather "layout-model" or "layout-manager" or "layout").
>
> For example you may want to say:
>
> ul > table
> {
>  display: list-item;
> }
>
> and this *must* not affect the way how table is replacing its children.

There are styles out there assuming that declaring "display:list-item"
affects the layout manager chosen (and I'm not sure it is correct to
blame them). If on the contrary you set "display-role:list-item", you
get the desider result of a table with an automatic ::marker

> That is why I think all table-** values are better to be removed from the
> 'display'. And single flow:table should be added instead.

We cannot do that. They're crafted in the stone of CSS21.

> With the wording "flow:table manages layout of contained tr,td,th and
> caption elements by using rules defined in HTML".
>
> And that is it.

AFAIK, neither the latest version of HTML (that is HTML5) nor that of
XHTML (that is XHTML2) define a rendering algorithm for tables.

> If someone want to define table alike layout for other DOM elements
> like list items then he/she may use any other method from the flow
> palette.
>
> As simple as that.
>
>
>> In addition, with "display-model", you don't need to define the
>> interaction with "display", that is just a shorthand: that is, you
>> don't need "flow:default".
>
> I've lost you here, sorry.

You don't need "flow:default" because you have
"display-model:inline-inside" and because anytime you set the
"display" you set also the "display-model".

>>>> 5) The properties for deciding in what direction shall elements be
>>>> layed out are "block-flow" and "writing-mode". This means that
>>>> "horizontal" and "vertical" should be replaced by something not
>>>> necessarily top-bottom. [CSS3TEXTLAYOUT]
>>>
>>> The 'flow' defines layout manager - principal way of laying out of
>>> elements.
>>> The 'direction' may specify direction for say flow:horizontal.
>>>
>>> I was thinking about adding flow:horizontal | horizontal-ltr |
>>> horizontal-rtl. Latter two should explicitly define the direction.
>>> So far it was not needed, flow:horizontal happened to be enough.
>>
>> If I say "block-flow:rl", flow:vertical must become visually
>> horizontal and right-to-left. So flow:block-progression and
>> flow:inline-progression; are proably better names (remember that
>> margins / paddings / borders are rotated when the orientation is
>> changed, so it doesn't make sense to keep vertical flow, when
>> flow:vertical)
>
> Why such simple things have to be so complex?

Because Chinese are billions and they look at their monitors from the
wrong side.


>>>> 6) The property for deciding if a sequence of inline boxes is splitted
>>>> in various line boxes is "text-wrap", so "horizontal" and
>>>> "horizontal-flow" are the same [CSS3TEXT]
>>>
>>> I am not sure I understand this. How is text-wrap related to
>>> the way of replacing blocks?
>>
>> Blocks are inside a line box (they're like inline-block), that is
>> wrapped according to the appropriate rules (text-wrap, white-space)
>
> Blocks are not text. Yes, they may contain text inside but
> why block replacement shall be governed by text-wrap and white-space?
>
> And yet as soon as you will start placing blocks into line-boxes you
> should clearly specify what things like 'vertical-align' mean exactly.

css3-linebox has definitions and properties for that, yes.

>>>> 7) The properties for deciding if a sequence of block boxes is
>>>> splitted in various column boxes are "column-count" and
>>>> "column-width", so "vertical" and "vertical-flow" are the same
>>>> [CSS3MULTICOL]
>>>
>>> Muulti-columns defines text flow rather than block flow.
>>> These are conceptually different things and I wouldn't mix them.
>>
>> No it is the same. If you put a block-formatting-context (the only
>
> No it is not.

Why?

>> kind of block that, to me, is not definible by "text flow") inside a
>> multicolumn block, the former is sized according to the column, it is
>> splitted if at the end of column (but you can avoid this, with
>> column-break-inside:avoid), and if there is not enough space, it is
>> put in the next column.
>>
>>> There are many practical cases where you will want to define
>>> exactly block flow. As an example:
>>> http://www.terrainformatica.com/htmlayout/images/selects2.jpg
>>> - various ways to define replacement of list items.
>>
>> uhm...
>> <body>
>> <label>Select:
>> <select>
>> <option>...
>> </select>
>> </label>
>> <label>Select multiple:
>> <select multiple="multiple">
>> <option>...
>> </select>
>> </label>
>> etc.
>> <label id="last">Select with h-flow
>> <select>
>> <option>...
>> </select>
>> </label>
>> </body>
>> with
>>
>> body {
>> column-count:2;
>> height:100vh;
>> }
>> label {
>> display:block;
>> heigth:25%;
>> }
>> select {
>> overflow:auto;
>> /* appearance:list-menu; */
>> }
>> #last {
>> float:bottom column;
>> }
>> #last > select > option {
>> width:25%;
>> display:inline-block;
>> /* appearance:menu-item; */
>> }
>> (if instead you wanted less than 4 items per row if space is not
>> enough, you can use min-width: if 25% is greater than the intrinsic
>> preferred width then there is more space than needed, else there is
>> less, and you get the intrinsic width, with blocks wrapped
>> appropriately)
>>
>> No flows, no XUL, no flex units. Just multicolumns and plain old
>> percentages.
>> (the content of <select>s, such as checkboxes and trees, is not relevant
>> now)
>>
>
> Here is one more example for you:
> http://www.terrainformatica.com/w3/various-flows.png
>
> First <select> is using this style:
>
>  select[name="iconview"]
>  {
>    flow:horizontal-flow; /* left-to-right , top-to-bottom */
>  }
>  select[name="iconview"] > option
>  {
>    width:0.25*; /* four items per row */
>    height:1*;   /* spans whole row */
>    border:1px solid silver;
>    margin:1px;
>  }
>
> It clearly shows difference between width:25%; and width:.25*;
>
> If space allows then items will be aligned in columns.
> But if it is not enough space (e.g. on mobile devices)
> it will start borrowing flex space from neighbors.
> Not so pretty as with say flow:table but keeps information
> readable and accessible.

As I said, I don't like that flows keep the intrinsic width (lines
should wrap), but it is a feature anyway, and it is worth introducing
the "fr" unit (not *!!) for width / height, given a meaning and a lot
of normative algorithms.

>
>>>> Giovanni

Received on Sunday, 12 April 2009 20:47:14 UTC