ABOUT THESE TESTS ----------------- 1. Testing environment =================== Platform: Windows XP Professional SP2 Screen resolution: 1024 x 768 pixels UI theme: Windows Classic Browser tested: Firefox 2, Opera 9, Internet Explorer 7. 2. Theory ==================== The following excerpts from http://lxr.mozilla.org/seamonkey/source/layout/doc/table_reflow_slides.html could give some useful hints. Table Reflow + Outer table reflows table and caption (if present) + Table reflows row groups in multiple passes * Pass 1 - unconstrained width, height and requests max elem width. * The table figures out the column widths (balances) given the style width constraints on the table, col groups, cols, cells the preferred and max element sizes of the cells (from the pass 1 reflow), and considers colspans * Pass 2 - cell widths are constrained by the column widths (heights are only constrained in paginated mode). + Table reflows row groups (continued) * The row group figures out the row heights given the its style height constraints its rows and cells and the actual heights of its rows and cells from the pass 2 reflow * If the table has a style height, it allocates extra height to its row groups, rows and cells. * In each pass, row groups reflow rows which reflow cells which reflow cell blocks Table Reflow Example
foo bar zap
tblO 030176CC r=0 a=8940,UC c=0,0 cnt=429 tbl 030178C4 r=0 a=8940,UC c=4470,UC cnt=430 rowG 03017A7C r=0 a=UC,UC c=UC,UC cnt=431 row 03017C08 r=0 a=UC,UC c=UC,UC cnt=432 cell 03017DA8 r=0 a=UC,UC c=UC,UC cnt=433 block 03017E08 r=0 a=UC,UC c=UC,UC cnt=434 block 03017E08 d=870,300 me=480 cell 03017DA8 d=930,360 me=540 cell 0301A8CC r=0 a=UC,UC c=UC,UC cnt=436 block 0301A92C r=0 a=UC,UC c=UC,UC cnt=437 block 0301A92C d=1335,300 me=465 cell 0301A8CC d=1395,360 me=525 row 03017C08 d=UC,360 rowG 03017A7C d=UC,360 rowG 03017A7C r=2 a=4470,UC c=4470,UC cnt=442 row 03017C08 r=2 a=4470,UC c=4470,UC cnt=443 cell 03017DA8 r=2 a=1755,UC c=1695,UC cnt=444 block 03017E08 r=2 a=1695,UC c=1695,UC cnt=445 block 03017E08 d=1695,300 cell 03017DA8 d=1755,360 cell 0301A8CC r=2 a=2625,UC c=2565,UC cnt=446 block 0301A92C r=2 a=2565,UC c=2565,UC cnt=447 block 0301A92C d=2565,300 cell 0301A8CC d=2625,360 row 03017C08 d=4470,360 rowG 03017A7C d=4470,360 tbl 030178C4 d=4500,450 tblO 030176CC d=4500,450 Key: r = reflow reason, 0 (initial), 2 (resize) a = avail w, h c = computed w, h d = desired w, h me = max elem w Table reflow optimizations + If the table is already balanced, pass 1 constrains the width (like a normal pass 2) based on the current column widths. The pass 2 will get skipped if the table doesn't need to rebalance. + Nested table reflowed with an unconstrained width (i.e. an ancestor is doing a pass 1 reflow) will only do a pass 1 reflow on its children + Outer table caches last avail width and avoids reflowing children if resize reflow is the same as previous + Table caches max element, preferred widths in case they are requested and it isn't rebalanced + Cell caches prior avail width. if this doesn't change, the row may not have to reflow the cell Table incremental reflow * Outer table is a target when a caption is added or removed (dirty) or the table or caption margin changes (style changed). * Caption is a target when it changes stylistically (style changed). * Table, row group, row, col group, col is a target when a child is added or removed (dirty) or it changes stylistically (style changed). * In the dirty cases, a target posted the reflow command in AppendFrames, InsertFrames, or DeleteFrame. * In the style change cases where a target is between the table and the cell, the table is told to rebalance. * When a target is the cell or below and the cell changes size, the row tells the table so it can decide if it needs to rebalance * When a target is inside the cell's block, the cell requests max element, preferred sizes of its block in case they change * After the table reflows the row group(s) containing the targets, if it rebalances, it then does a pass 2 reflow. Now it's useful to compare the above mentioned algorithms with the automatic table layout algorithm described in the specs (see http://www.w3.org/TR/CSS21/tables.html#auto-table-layout). The first thing to keep in mind is: CSS does not define an "optimal" layout for tables since, in many cases, what is optimal is a matter of taste. CSS does define constraints that user agents must respect when laying out a table. User agents may use any algorithm they wish to do so, and are free to prefer rendering speed over precision, except when the "fixed layout algorithm" is selected. Note that this section overrides the rules that apply to calculating widths as described in section 10.3. In particular, if the margins of a table are set to '0' and the width to 'auto', the table will not automatically size to fill its containing block. However, once the calculated value of 'width' for the table is found (using the algorithms given below or, when appropriate, some other UA dependant algorithm) then the other parts of section 10.3 do apply. Therefore a table can be centered using left and right 'auto' margins, for instance. The automatic table layout algorithm is described as follows: In this algorithm (which generally requires no more than two passes), the table's width is given by the width of its columns (and intervening borders). This algorithm reflects the behavior of several popular HTML user agents at the writing of this specification. UAs are not required to implement this algorithm to determine the table layout in the case that 'table-layout' is 'auto'; they can use any other algorithm even if it results in different behavior. Input to the automatic table layout must only include the width of the containing block and the content of, and any CSS properties set on, the table and any of its descendants. The actual algorithm is non-normative: This algorithm may be inefficient since it requires the user agent to have access to all the content in the table before determining the final layout and may demand more than one pass. Column widths are determined as follows: 1. Calculate the minimum content width (MCW) of each cell: the formatted content may span any number of lines but may not overflow the cell box. If the specified 'width' (W) of the cell is greater than MCW, W is the minimum cell width. A value of 'auto' means that MCW is the minimum cell width. Also, calculate the "maximum" cell width of each cell: formatting the content without breaking lines other than where explicit line breaks occur. 2. For each column, determine a maximum and minimum column width from the cells that span only that column. The minimum is that required by the cell with the largest minimum cell width (or the column 'width', whichever is larger). The maximum is that required by the cell with the largest maximum cell width (or the column 'width', whichever is larger). 3. For each cell that spans more than one column, increase the minimum widths of the columns it spans so that together, they are at least as wide as the cell. Do the same for the maximum widths. If possible, widen all spanned columns by approximately the same amount. 4. For each column group element with a 'width' other than 'auto', increase the minimum widths of the columns it spans, so that together they are at least as wide as the column group's 'width'. This gives a maximum and minimum width for each column. Column widths influence the final table width as follows: 1. If the 'table' or 'inline-table' element's 'width' property has a computed value (W) other than 'auto', the property's value as used for layout is the greater of W and the minimum width required by all the columns plus cell spacing or borders (MIN). If W is greater than MIN, the extra width should be distributed over the columns. 2. If the 'table' or 'inline-table' element has 'width: auto', the table width used for layout is the greater of the table's containing block width and MIN. However, if the maximum width required by the columns plus cell spacing or borders (MAX) is less than that of the containing block, use MAX. A percentage value for a column width is relative to the table width. If the table has 'width: auto', a percentage represents a constraint on the column's width, which a UA should try to satisfy. (Obviously, this is not always possible: if the column's width is '110%', the constraint cannot be satisfied.). Note. In this algorithm, rows (and row groups) and columns (and column groups) both constrain and are constrained by the dimensions of the cells they contain. Setting the width of a column may indirectly influence the height of a row, and vice versa. Another thing to keep in mind are the computations used for the fixed table layout algorithm: With this (fast) algorithm, the horizontal layout of the table does not depend on the contents of the cells; it only depends on the table's width, the width of the columns, and borders or cell spacing. The table's width may be specified explicitly with the 'width' property. A value of 'auto' (for both 'display: table' and 'display: inline-table') means use the automatic table layout algorithm. However, if the table is a block-level table ('display: table') in normal flow, a UA may (but does not have to) use the algorithm of 10.3.3 to compute a width and apply fixed table layout even if the specified width is 'auto'. In the fixed table layout algorithm, the width of each column is determined as follows: 1. A column element with a value other than 'auto' for the 'width' property sets the width for that column. 2. Otherwise, a cell in the first row with a value other than 'auto' for the 'width' property determines the width for that column. If the cell spans more than one column, the width is divided over the columns. 3. Any remaining columns equally divide the remaining horizontal table space ( minus borders or cell spacing). The width of the table is then the greater of the value of the 'width' property for the table element and the sum of the column widths (plus cell spacing or borders). If the table is wider than the columns, the extra space should be distributed over the columns. If a subsequent row has more columns than the greater of the number determined by the table-column elements and the number determined by the first row, then additional columns must not be rendered. When using 'table-layout: fixed', authors should not omit columns from the first row. In this manner, the user agent can begin to lay out the table once the entire first row has been received. Cells in subsequent rows do not affect column widths. Any cell that has content that overflows uses the 'overflow' property to determine whether to clip the overflow content.