- From: Andrew Fedoniouk <news@terrainformatica.com>
- Date: Wed, 04 Jun 2008 20:09:37 -0700
- To: dbaron@dbaron.org, www-style@w3.org
- Message-ID: <484758F1.6030800@terrainformatica.com>
L. David Baron wrote: > On Wednesday 2008-06-04 17:50 -0700, Andrew Fedoniouk wrote: >> Consider following markup: >> >> <body> >> <div>On the top</div> >> <div>On the bottom</div> >> </body> >> >> and we would like to "stick" second div to the bottom and first one to >> the top of the view. How would you >> accomplish that with XUL flexes? Probably I have missed something but >> that is impossible with XUL flexes. > > <body style="display:box; box-orient:vertical"> > <div>On the top</div> > <div style="box-flex: 1"></div> <!-- maybe needs 'display: box' ? --> > <div>On the bottom</div> > </body> David, I think you already know why this is bad. div in the middle is not a solution if we speak about CSS. > >> Flexibility is really a length unit rather than some property. > > No, since some layout models (traditional document layout) use one > dimension as input and the other as output; you can only flex in a > dimension that is input to the algorithm. In the existing CSS > model, in many cases, there is no sensible height that is input to > the algorithm (or, depending on how you look at it, multiple heights > that might be of interest). > I am not sure I understand this: "you can *only* flex in a dimension that is input to the algorithm" This <body><table width=100% height=100%></table></body> works perfectly well in Gecko as in other engines. (In html/table percents behave as flex units) So we already know how to flex things in both dimensions. That is why I am confused by your statement. Flexes defined in the context of some container. Content is measured normally (position:static) and if there is a free space left then this free space is getting distributed among all lengths having flex units - parts competing for free space. For inline-block elements container is a line box so this: <p>Input:<input style="width:1*; height:1*" /><br/> Input #2:<input style="width:1*; height:1*" /></p> will be rendered as: |Input:[~~~~~~~input~~~~~~~~]| |Input #2:[~~~~~input~~~~~~~]| Height if these inputs (height:1*) will be set to the height of correspondent line box. For containers that have display-model:block-inside flexes of children are computed against width and height such containers. For children of flow:vertical containers: width:auto, margin-left/right:auto are exactly width:1*, margin-left/right:1* - nothing new here. and height:1* and/or margin-left/right:1* declares this block as competing for free space distribution. If such container has declared height greater than intrinsic height of the content then it means that there is a free space. This space can be distributed among flexes. Flex distribution algorithm is simple. I've attached implementation that I use ( libra.h ). -- Andrew Fedoniouk. http://terrainformatica.com
//| //|----------------------------------------------------------------------+ //| H-SMILE core | //|----------------------------------------------------------------------+ //| Copyright (c) 2001-2008 Andrew Fedoniouk and | //| Terra Informatica Software, Inc. | //|----------------------------------------------------------------------+ //| //| //| Flex (Springs) distribution algorithm implementation. //| namespace html { class libra { public: struct item { int vmin; int vmax; int v; // computed value int p; // weight (>0) }; int ptotal; int vtotalmin; int autos; int freespace; spring_engine() { clear(); } void clear() { ptotal = 0; vtotalmin = 0; autos = 0; freespace = 0; } // adds flex item to distribute // param: valmin/valmax, min/max constraints. // param: percent - weight void add(int valmin, int valmax, int percent) { item i; i.v = i.vmin = valmin; if(valmax && (valmax < valmin)) i.vmax = valmin; else i.vmax = valmax; i.p = percent; ptotal += percent; if (valmax) ++autos; if(percent == 0) vtotalmin += valmin; add_item(i); } inline int val(int i) { return (head() + i)->v; } // param: total, total container width to distribute. // param: max100, flag - true - do 100%% normalization // return: actual content width. inline int calc(int total, bool max100 = true) { freespace = total - vtotalmin; if(freespace <= 0 || ptotal == 0) return vtotalmin; item *start = head(); item *i = start; item *end = tail(); int ptotalmin = ptotal; if(max100) { if (ptotal < 100) ptotal = 100; // key point } ptotalmin = ptotal - ptotalmin; int save_ptotal = ptotal; // worst case is n*n scans of the set. for(item* iteration = start; iteration < end; ++iteration) { for(i = start;i < end; ++i) { if(i->p == 0) continue; // skip elements having fixed size if( ptotal == 0 ) { //assert(false); break; } int v = (freespace * i->p) / ptotal; // v, value - width candidate if( v < i->vmin ) { // minimum reached, exclude from distribution list i->v = i->vmin; vtotalmin += i->v; save_ptotal -= i->p; i->p = 0; break; } if(autos && i->vmax && ( v > i->vmax )) { // maximum reached, exclude from distribution list i->v = i->vmax; vtotalmin += i->v; save_ptotal -= i->p; i->p = 0; break; } i->v = v; freespace -= v; ptotal -= i->p; if(ptotal <= ptotalmin) break; //done } if(ptotal <= ptotalmin || freespace <= 0) break; //done ptotal = save_ptotal; freespace = total - vtotalmin; } return total - freespace; } virtual void add_item(const item& it) = 0; virtual item* head() = 0; virtual item* tail() = 0; }; }
Received on Thursday, 5 June 2008 03:10:25 UTC