tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rowspan-height-redistribution.html (14352B)


      1 <!doctype html>
      2 <title>ROWSPAN redistribution</title>
      3 <script src='/resources/testharness.js'></script>
      4 <script src='/resources/testharnessreport.js'></script>
      5 <script src="/resources/check-layout-th.js"></script>
      6 <link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
      7 <link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
      8 <link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout" />
      9 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4418" />
     10 <style>
     11  main table {
     12    margin-top: 8px;
     13    border-collapse: collapse;
     14    background: rgba(0,0,255,0.1);
     15    background-image: linear-gradient(45deg, #DDD 25%, transparent 25%), linear-gradient(-45deg, #DDD 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #DDD 75%), linear-gradient(-45deg, transparent 75%, #DDD 75%);
     16    background-size: 20px 20px;
     17    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
     18  }
     19  .sizer {
     20    width: 30px;
     21    height: 100px;
     22  }
     23  main tbody tr:nth-child(odd) {
     24    background: rgba(255,255,0,1.0);
     25  }
     26  main tbody tr:nth-child(even) {
     27    background: rgba(255,165,0,1.0);
     28  }
     29  main td div {
     30    background: radial-gradient(ellipse at center, rgba(255,255,255,0.5) 0%, rgba(0,255,0,0.7) 100%);
     31  }
     32  main .td-padding td {
     33    padding: 2px;
     34  }
     35  main .td-padding-xl td {
     36    padding: 10px;
     37  }
     38 </style>
     39 <main>
     40 <h1>ROWSPAN > 1 to row distribution</h1>
     41 <p>The algorithm has not been standardized. This is my understanding of how it works.</p>
     42 <ol>
     43  <li>rowspan>1 TDs are sorted:</li>
     44    <ol>
     45      <li>If TD span the same rows, taller TD is distributed first.</li>
     46      <li>If one TD is fully enclosed by another, inner TD is distributed first.</li>
     47      <li>Otherwise, higher TD is distributed first.</li>
     48    </ol>
     49  <li>Each rowspan>1 TD's height is distributed as following</li>
     50    <ol>
     51      <li>rowspan > 1 TDs have height TDh, span N rows. N rows have total height of Rh. TDh - Rh height, Dh, must be distributed as follows.</li>
     52      <li>If percentage resolution size is available (this happens when redistributiong table/section height), percentage rows grow to their percentage size, proportional to (percentage size - current size). Dh shrinks by distributed height. Justification: explicit percentage rows should grow to their percentage.</li>
     53      <li>Rows that originate rowspan>1 cells get all the Dh height, distributed evenly. Justification: rowspan>1 rows are likely to need to grow later. If there are multiple rowspan>1 cells, there can be multiple originating rows.</li>
     54      <li>Unconstrained non-empty rows grow, proportional to their existing height.</li>
     55      <li>If all rows are empty, last row gets all the height. Justification: ???</li>
     56      <li>Contstrained rows grow in proportion to current height.</li>
     57    </ol>
     58  </ol>
     59 <p class="error">It is unclear what the existing ChromeLegacy/FF algorithms do for distribution over rowspan>1 and empty cells. <a href="https://dxr.mozilla.org/mozilla-central/source/layout/tables/nsTableRowGroupFrame.cpp#509">FF special cases</a> "there is no cell originating in the row with owspan=1 and there are at least 2 cells spanning the row. Chrome Legacy also tries to do something similar, but they disagree on what. TablesNG will try to ship without special cases.</p>
     60 <p class="error">Safari fails most of these tests</p>
     61 <p>Color scheme</p>
     62 <table>
     63  <tr>
     64    <td>odd rows are yellow</td>
     65  </tr>
     66  <tr>
     67    <td>even rows are orange</td>
     68  </tr>
     69  <tr>
     70    <td><div style="height:50px">inner divs have a green gradient</div>
     71    </td>
     72  </tr>
     73  <tr>
     74    <td>row</td>
     75  </tr>
     76  <tr>
     77    <td>row</td>
     78  </tr>
     79 <tr>
     80    <td>row</td>
     81  </tr>
     82  <tr>
     83    <td>row</td>
     84  </tr>
     85 
     86 </table>
     87 <h2>Unconstrained rows</h2>
     88 <p>Rows whose height is not fixed or percent are unconstrained.</p>
     89 <p class="testdesc">Unconstrained rows
     90 Unconstrained rows are redistributed proportionally. Rows are constrained if their height is fixed, or percent.</p>
     91 <table>
     92  <tbody>
     93    <tr data-expected-height="50">
     94      <td>0,0</td>
     95      <td rowspan="2"><div class="sizer"></div></td>
     96    </tr>
     97    <tr data-expected-height="50">
     98      <td>0,1</td>
     99    </tr>
    100 </table>
    101 
    102 <p class="testdesc">Unconstrained rows with zero height do not grow.</p>
    103 <table>
    104  <tbody>
    105    <tr data-expected-height="50">
    106      <td>0,0</td>
    107      <td rowspan="3"><div class="sizer"></div></td>
    108    </tr>
    109    <tr data-expected-height="0">
    110    </tr>
    111    <tr data-expected-height="50">
    112      <td>0,2</td>
    113    </tr>
    114 </table>
    115 
    116 <p class="testdesc">rowspan>1 is zero height, spanned rows have height.</p>
    117 <table>
    118  <tbody>
    119    <tr data-expected-height="0">
    120      <td></td>
    121      <td rowspan="3"><div class="sizer"></div></td>
    122      <td></td>
    123    </tr>
    124    <tr data-expected-height="50">
    125      <td>1,0</td>
    126      <td></td>
    127    </tr>
    128    <tr data-expected-height="50">
    129      <td>2,0</td>
    130      <td></td>
    131    </tr>
    132 </table>
    133 
    134 <p class="testdesc">Unconstrained rows are redistributed proportionally to heights</p>
    135 <table>
    136  <tbody>
    137    <tr data-expected-height="75">
    138      <td><div style="height:45px">0,0</div></td>
    139      <td rowspan="2"><div class="sizer"></div></td>
    140    </tr>
    141    <tr data-expected-height="25">
    142      <td><div style="height:15px">0,1</div></td>
    143    </tr>
    144 </table>
    145 
    146 <h2>Fixed rows</h2>
    147 
    148 <p class="testdesc">Constrained fixed rows
    149 do not grow if there are unconstrained ones</p>
    150 <p class="error">Edge grows constrained rows too</p>
    151 <table>
    152  <tbody>
    153    <tr style="height: 30px" data-expected-height="30">
    154      <td>0,0 30px</td>
    155      <td rowspan="2"><div class="sizer"></div></td>
    156    </tr>
    157    <tr data-expected-height="70">
    158      <td>0,1</td>
    159    </tr>
    160 </table>
    161 
    162 <p class="testdesc"> Constrained fixed rows
    163 grow proportionally to their size if there are no unconstrained rows</p>
    164 <table>
    165  <tbody>
    166    <tr style="height: 20px" data-expected-height="25">
    167      <td>20</div></td>
    168      <td rowspan="3"><div class="sizer"></div></td>
    169    </tr>
    170    <tr style="height: 20px" data-expected-height="25">
    171      <td>20</td>
    172    </tr>
    173    <tr style="height: 40px" data-expected-height="50">
    174      <td>40</td>
    175    </tr>
    176 </table>
    177 
    178 <h2>Percent rows</h2>
    179 
    180 <p class="testdesc">Constrained percent rows
    181 grow like unconstrained ones when percent resolution size is undefined.</p>
    182 <p class="error">FF always treats percent rows as constrained. Chrome legacy does resolve percentage against final height of the table. I do not think that can work. Edge follows NG.</p>
    183 <table>
    184  <tbody>
    185    <tr style="height: 30%" data-expected-height="50">
    186      <td>0,0 30%</td>
    187      <td rowspan="2"><div class="sizer"></div></td>
    188    </tr>
    189    <tr data-expected-height="50">
    190      <td>0,1</td>
    191    </tr>
    192    <tr style="height:100px"><td>100px</td></tr>
    193 </table>
    194 
    195 
    196 <p class="testdesc">Percent rows with zero height
    197 do not grow.</p>
    198 <p class="error">Legacy Chrome has a strange gap between rows</p>
    199 <table>
    200  <tbody>
    201    <tr data-expected-height="50">
    202      <td>0,0</td>
    203      <td rowspan="3"><div class="sizer"></div></td>
    204    </tr>
    205    <tr style="height:10%;background:red" data-expected-height="0">
    206    </tr>
    207    <tr data-expected-height="50">
    208      <td>2,0</td>
    209    </tr>
    210 </table>
    211 
    212 <h2>Order of rowspan distribution</h2>
    213 
    214 
    215 <p class="testdesc">If cells span the same rows, bigger cell is distributed first
    216 Not sure how to test this, I think it is just an optimization, there is no observable effect.
    217 <p class="error">FF and Legacy Chrome unexpectedly distribute height evenly between rows in the first test case. Edge and TablesNG do not.</p>
    218 <table>
    219  <tr data-expected-height=0>
    220    <td rowspan=3><div style="height:50px"></div></td>
    221    <td rowspan=3><div style="height:99px"></div></td>
    222  </tr>
    223  <tr data-expected-height=0>
    224  </tr>
    225  <tr data-expected-height=99>
    226  </tr>
    227  <tr>
    228    <td>bottom</td>
    229    <td>bottom</td>
    230  </tr>
    231 </table>
    232 <table>
    233  <tr data-expected-height=0>
    234    <td rowspan=3><div style="height:50px"></div></td>
    235    <td rowspan=3><div style="height:99px"></div></td>
    236    <td style="width:20px"></td>
    237  </tr>
    238  <tr data-expected-height=0>
    239    <td></td>
    240  </tr>
    241  <tr data-expected-height=99>
    242    <td></td>
    243  </tr>
    244  <tr>
    245    <td>bottom</td>
    246    <td>bottom</td>
    247  </tr>
    248 </table>
    249 <table>
    250  <tr data-expected-height=0>
    251    <td rowspan=3><div style="height:99px;width:20px"></div></td>
    252  </tr>
    253  <tr></tr>
    254  <tr data-expected-height=99></tr>
    255 <tr>
    256    <td>bottom</td>
    257    <td>bottom</td>
    258  </tr>
    259 </table>
    260 
    261 
    262 <p class="testdesc">If one cell is fully enclosed by another, inner cell wins.
    263 <p class="error">Not in Edge</p>
    264 <table>
    265  <tr data-expected-height=0>
    266    <td rowspan=4><div style="height:50px;width:20px"></div></td>
    267    <td></td>
    268  <tr data-expected-height=0>
    269    <td></td>
    270    <td rowspan=2><div style="height:100px;width:20px"></div></td>
    271  </tr>
    272  <tr data-expected-height=100></tr>
    273  <tr data-expected-height=0></tr>
    274 </tr>
    275 </table>
    276 
    277 <p class="testdesc">First row wins.
    278 rowspan-4 distributes 50 to last empty row, row3. rowspan-3 distributes 100px to only nonempty row, row3.
    279 <p class="error">Edge disagrees here.</p>
    280 <table>
    281  <tr data-expected-height=0>
    282    <td rowspan=4><div style="height:50px;width:20px"></div></td>
    283    <td></td>
    284  <tr data-expected-height=0></tr>
    285  <tr data-expected-height=0></tr>
    286  <tr data-expected-height=100>
    287    <td></td>
    288    <td rowspan=3><div style="height:100px;width:20px"></div></td>
    289  </tr>
    290  <tr data-expected-height=0></tr>
    291  <tr data-expected-height=0></tr>
    292 </tr>
    293 </table>
    294 
    295 <h2>Rowspan distribution over empty rows.</h2>
    296 
    297 <p class="testdesc">Rowspans that span non-existent rows
    298 Span is truncated so only existing rows are spanned.</p>
    299 <table>
    300  <tbody data-expected-height="100">
    301    <tr>
    302      <td data-expected-height="50">0,0</td>
    303      <td data-expected-height="100" rowspan="5"><div style="height:100px;">rowspan 5</div></td>
    304    </tr>
    305    <tr>
    306      <td data-expected-height="50">1,0</td>
    307    </tr>
    308    <tr data-expected-height="0"></tr>
    309  </tbody>
    310  <tbody>
    311    <tr>
    312      <td>body 2</td>
    313    </tr>
    314  </tbody>
    315 </table>
    316 
    317 <p class="testdesc">Rowspan spans only empty rows
    318 Last spanned row gets all the height.
    319 <p class="error">Edge distributes height to all empty rows, not just last.</p>
    320 <table>
    321  <tr>
    322    <td>first row</td>
    323  </tr>
    324  <tr data-expected-height=0>
    325    <td></td>
    326    <td rowspan=5><div style="height:100px;width:30px;"></div></td>
    327  </tr>
    328  <tr data-expected-height=0><td></td></tr>
    329  <tr data-expected-height=0><td></td></tr>
    330  <tr data-expected-height=0><td></td></tr>
    331  <tr data-expected-height=100><td></td></tr>
    332  <tr>
    333    <td>last row</td>
    334  </tr>
    335 </table>
    336 
    337 <p class="testdesc">TD is not considered empty if it has padding, but no content
    338 <table>
    339  <tr>
    340    <td>first row</td>
    341  </tr>
    342  <tr data-expected-height=0>
    343    <td></td>
    344    <td style="height:100px" rowspan=3></td>
    345  </tr>
    346  <tr data-expected-height=100><td style="padding:2px"></td></tr>
    347  <tr data-expected-height=0></tr>
    348  <tr>
    349    <td>last row</td>
    350  </tr>
    351 </table>
    352 
    353 <p class="testdesc">row with an empty tall cell is not considered empty.
    354 <p class="error">
    355 <table>
    356  <tr>
    357    <td rowspan=5><div style="height:100px">rowspan</div></td>
    358    <td></td>
    359    <td></td>
    360  </tr>
    361  <tr data-expected-height=100>
    362    <td rowspan=5></td>
    363    <td></td>
    364  </tr>
    365  <tr></tr>
    366  <tr></tr>
    367  <tr></tr>
    368  <tr></tr>
    369 </table>
    370 
    371 <p class="testdesc">Empty rows with border-spacing big enough for rowspan cell
    372 rows are 0 height, cell spans the entire table.
    373 <table style="border-spacing:20px;border-collapse:separate " data-expected-height=100>
    374  <tr data-expected-height=0>
    375    <td rowspan=4><div style="height:60px;width:40px"></div></td>
    376  </tr>
    377  <tr data-expected-height=0></tr>
    378  <tr data-expected-height=0></tr>
    379  <tr data-expected-height=0></tr>
    380 </table>
    381 
    382 <p class="testdesc">row with a non-empty rowspan>0 cell is empty.
    383 Distributes to all rows except start row?
    384 <p class="error">
    385 <table>
    386  <tr>
    387    <td rowspan=5><div style="height:100px">rowspan</div></td>
    388    <td></td>
    389  </tr>
    390  <tr data-expected-height=100>
    391    <td rowspan=5><div style="height:100px">rowspan</div></td>
    392  </tr>
    393  <tr data-expected-height=0></tr>
    394  <tr data-expected-height=0></tr>
    395  <tr data-expected-height=0></tr>
    396  <tr></tr>
    397  <tr></tr>
    398 </table>
    399 <table>
    400  <tr>
    401    <td rowspan=5><div style="height:100px">rowspan</div></td>
    402    <td></td>
    403  </tr>
    404  <tr data-expected-height=100>
    405    <td>yo</td>
    406  </tr>
    407  <tr data-expected-height=0></tr>
    408  <tr data-expected-height=0></tr>
    409  <tr data-expected-height=0></tr>
    410 </table>
    411 
    412 
    413 <p class="testdesc">Distribution over rowspan > 1 rows
    414 Distribution over rowspan > 1 rows
    415 
    416 <table class="td-padding-xl" data-expected-height=360>
    417  <tr>
    418    <td rowspan=6><div style="width:50px;height:280px"></div></td>
    419    <td></td>
    420    <td></td>
    421  </tr>
    422  <tr>
    423    <td></td>
    424  </tr>
    425  <tr style="height:30%;background:purple">
    426    <td data-expected-height=20></td>
    427  </tr>
    428  <tr data-expected-height=110>
    429    <td rowspan=7 ></td>
    430  </tr>
    431  <tr data-expected-height=110>
    432    <td rowspan=17 ><div style="width:50px;height:40px"></div></td>
    433  </tr>
    434  <tr>
    435    <td></td>
    436  </tr>
    437  <tr>
    438    <td></td>
    439  </tr>
    440    <tr>
    441    <td></td>
    442  </tr>
    443    <tr>
    444    <td></td>
    445  </tr>
    446 </table>
    447 
    448 <p class="testdesc">Distribution of table height over rowspan > 1 rows
    449 If there are any unconstrained non-empty rows, they get it.
    450 When all rows are empty, last row takes it</p>
    451 <table class="td-padding-xl" style="height:460px">
    452  <tr>
    453    <td rowspan=6><div style="width:50px;height:280px" data-expected-height=280></div></td>
    454    <td></td>
    455    <td></td>
    456  </tr>
    457  <tr>
    458    <td></td>
    459  </tr>
    460  <tr style="height:30%;background:purple" data-expected-height=120>
    461    <td ></td>
    462  </tr>
    463  <tr data-expected-height=110>
    464    <td rowspan=7 ></td>
    465  </tr>
    466  <tr data-expected-height=110>
    467    <td rowspan=17><div style="width:50px;height:40px"></div></td>
    468  </tr>
    469  <tr>
    470    <td></td>
    471  </tr>
    472  <tr>
    473    <td></td>
    474  </tr>
    475    <tr>
    476    <td></td>
    477  </tr>
    478    <tr>
    479    <td></td>
    480  </tr>
    481 </table>
    482 
    483 <p class="testdesc">Distribution of rowspan over percentage rows
    484 Percentage rows are considered empty if they cannot resolve</p>
    485 <table>
    486  <tbody>
    487    <tr style="height:20%">
    488      <td rowspan=3><div style="height:100px;width:100px"></div></td>
    489      <td></td>
    490    </tr>
    491    <tr style="height:30%">
    492      <td></td>
    493    </tr>
    494    <tr data-expected-height=100 style="height:50%">
    495      <td></td>
    496    </tr>
    497  </tbody>
    498 </table>
    499 
    500 </main>
    501 <script>
    502  checkLayout("table");
    503 </script>