Re: [CSS3] Flexible Flow Module, proposal.

Giovanni Campagna wrote:
> 2009/4/11 Andrew Fedoniouk <>:
>> 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:
>> 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?

What to do if I only need to flex only margins as here:
to align the element with respect of its and its siblings intrinsic 

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.

>> 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
>>> <>
>>> and you can find a proposal for the Flexible Box at
>>> <>.
>> 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.

I think that XUL 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.

>>> 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)
>> '*' units are already used in the CSS Grid module and CSS Template Layout..
>> 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.
> 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:

{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.

>>> 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)

Chapter #2.

So this:


is in fact:


And this case is in principle not reproducible by the calc().

> 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.

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 

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.

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

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.

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

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.

>>> 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?

>>> 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.

>>> 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
>> 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.

> 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:
>> - 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:

First <select> is using this style:

     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;

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.

>>> Giovanni

Andrew Fedoniouk.

Received on Sunday, 12 April 2009 20:11:57 UTC