summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-tables/tentative
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/css/css-tables/tentative
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-tables/tentative')
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/baseline-table.html179
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/baseline-td.html124
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/caption.html137
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/col-collapse-table-size.html88
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/colgroup-col.html122
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/colspan-redistribution.html621
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/column-widths.html300
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/element-sizing.html34
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed-ref.html30
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed.html68
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-ref.html44
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column.html56
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed-ref.html60
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed.html53
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-ref.html68
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row.html55
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell-ref.html33
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell.html39
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table-ref.html32
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table.html37
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/position-sticky-container.html170
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/rowspan-height-redistribution.html503
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-fixed-distribution.html9
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-percent-distribution.html9
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/support/README13
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/support/table-tentative.css34
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-fixed-minmax.html146
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-height-redistribution.html317
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-minmax.html144
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-quirks.html76
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed-padding.html267
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed.html374
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution.html351
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/tbody-height-redistribution.html144
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-001.html197
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-002.html123
-rw-r--r--testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-003.html148
37 files changed, 5205 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-tables/tentative/baseline-table.html b/testing/web-platform/tests/css/css-tables/tentative/baseline-table.html
new file mode 100644
index 0000000000..1507bf656f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/baseline-table.html
@@ -0,0 +1,179 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<meta name="flags" content="ahem">
+<title>TABLE baseline</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/" />
+<link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align" />
+<style>
+ main table {
+ display: inline-table;
+ border: 15px solid green;
+ background: gray;
+ width: 0px;
+ height: 0px;
+ vertical-align:baseline;
+ border-spacing: 0;
+ }
+ main td {
+ background: #BFB;
+ padding: 4px;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+ .container {
+ position: relative;
+ outline: black dotted 1px;
+ height: 100px;
+ width: 400px;
+ font: 50px/1 Ahem; /* baseline is 40px */
+ }
+</style>
+<main>
+<h2>&lt;TABLE&gt; baseline tests</h2>
+
+<p>Empty table's baseline is bottom of table's border box.</p>
+<div class="container">
+ Xp<table data-offset-y="10">
+ </table>
+</div>
+
+<p>Empty body's baseline is bottom of table's border box.</p>
+<div class="container">
+ Xp<table data-offset-y="10">
+ <tbody>
+ </tbody>
+ </table>
+</div>
+
+<p>Empty row's baseline is center of the row.</p>
+<div class="container">
+ Xp<table data-offset-y="25">
+ <tbody>
+ <tr></tr>
+ </tbody>
+ </table>
+</div>
+
+<p>First row defines baseline even if empty.</p>
+<div class="container">
+ Xp<table style="font: 12px fixed" data-offset-y="25">
+ <tbody>
+ <tr></tr>
+ <tr><td>1,0</td></tr>
+ </tbody>
+ </table>
+</div>
+
+<p>Cell's baseline defined row's baseline only if cell is vertical-align:baseline.</p>
+<div class="container">
+ Xp<table style="font-size: 24px" data-offset-y="2">
+ <tbody>
+ <tr><td style="vertical-align:baseline">Xp</td></tr>
+ </tbody>
+ </table></div>
+</div>
+<div class="container">
+ Xp<table style="font-size:24px" data-offset-y="0">
+ <tbody>
+ <tr><td style="vertical-align:middle">Xp</td></tr>
+ </tbody>
+ </table>
+</div>
+
+
+<p>Table's vertical-align: top.</p>
+<div class="container">
+ Xp<table style="vertical-align:top" data-offset-y="0"></table>
+</div>
+
+<p>Table's vertical-align: middle. </p>
+<div class="container">
+ Xp<table style="vertical-align:middle" data-offset-y="5"></table>
+</div>
+
+<p>Table's vertical-align: bottom. </p>
+<div class="container">
+ Xp<table style="vertical-align:bottom" data-offset-y="20"></table>
+</div>
+
+<p>Table's top/middle/bottom combined. </p>
+<div class="container">
+ Xp<table style="vertical-align:top" data-offset-y="0"></table>
+ <table style="vertical-align:middle" data-offset-y="5"></table>
+ <table style="vertical-align:bottom" data-offset-y="20"></table>
+</div>
+
+<p>Two rows empty, 1st row has css height.</p>
+<div class="container">
+ Xp<table data-offset-y=25 data-expected-height=50>
+ <tr style="height:20px"></tr>
+ <tr></tr>
+ </table>
+</div>
+
+<p>First row empty with css height, 2 row has content, </p>
+<div class="container">
+ Xp<table data-offset-y=25 data-expected-height=68>
+ <tr style="height:20px"></tr>
+ <tr><td style="font-size:10px">X</td></tr>
+ </table>
+</div>
+
+<p>Empty rowspanned cells should not set baseline. This test might not be per-spec, distribution of empty cells over empty rows differs between browsers.</p>
+<div class="container">
+ Xp<table>
+ <tr>
+ <td rowspan=2 style="height:80px"></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ </table><div style="display:inline-block" data-offset-y=15>pX</div>
+</div>
+
+<p>Block level table inside inline block does not produce a baseline.</p>
+<div class="container" style="font: 10px/1 Ahem;width:500px">
+ Xp<br>Xp<table
+ title="inline table produces a baseline"
+ data-offset-y=33><td style="vertical-align:baseline">Xp</td></table>
+ <div style="display:inline-block;height:50px;background:yellow;width:50px;"
+ title="empty inline block baseline is bottom of the block"
+ data-offset-y=10
+ ></div>
+ <div style="display:inline-block;height:50px;background:yellow;width:50px;"
+ title="inline block's content defines its baseline"
+ data-offset-y=52
+ >X</div>
+ <div style="display:inline-block;height:50px;background:yellow"
+ title="table inside inline block does not produce a baseline"
+ data-offset-y=10
+ ><table style="display:table"><td style="vertical-align:baseline">X</td></table></div>
+ <div style="display:inline-block;height:50px;background:yellow"
+ title="but inline table inside inline block does produce a baseline"
+ data-offset-y=33
+ ><table style="display:inline-table"><td style="vertical-align:baseline">X</td></table></div>
+</div>
+
+<!-- anonymous-table-no-baseline-align replica -->
+<p>Anonymous tables should not generate baselines</p>
+<div class="container">Xp
+ <div style="height:60px;width:100px;display:inline-block;background:green"
+ data-offset-y=0>
+ <div style="display:table-cell;vertical-align:middle;color:yellow">&nbsp;</div>
+ </div>
+ <div style="height:60px;width:100px;display:inline-block;background:green"
+ data-offset-y=0>
+ <div style="display:table-cell;vertical-align:middle;color:yellow">>&nbsp;<br>&nbsp;<br></div>
+ </div>
+</div>
+</main>
+<script>
+ checkLayout(".container");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/baseline-td.html b/testing/web-platform/tests/css/css-tables/tentative/baseline-td.html
new file mode 100644
index 0000000000..4090c5db64
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/baseline-td.html
@@ -0,0 +1,124 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<meta name="flags" content="ahem">
+<title>TD baseline</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/" />
+<link rel="help" href="https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align" />
+<style>
+ table {
+ background: #AAA;
+ border-spacing: 8px 0px;
+ }
+ td {
+ padding: 0;
+ background: #BFB;
+ }
+ .ahem {
+ font: 25px/2 Ahem;
+ }
+ .ahem td, .ahem .display-cell {
+ font: 25px/2 Ahem;
+ color: rgba(0,120,0, 0.5);
+ }
+ .vgrad {
+ background: linear-gradient(180deg, #DDD 0%, #DDD 60%, #999 60%, #999 100%) !important;
+ }
+ .m {
+ display:inline-block;
+ }
+ .display-table {
+ display:table;
+ background: #AAA;
+ border-spacing: 8px 0px;
+ }
+ .display-cell {
+ display:table-cell;
+ padding: 0;
+ }
+</style>
+<main>
+<h2>&lt;TD&gt; baseline tests</h2>
+
+<p class="testdesc">All the baseline values.
+Many text values map to plain baseline. </p>
+<table style="height:100px" class="ahem vgrad">
+ <td style="font: 75px/1 Ahem;vertical-align:baseline;"><div class="m" data-offset-y=0>Xp</div></td>
+ <td style="" title="default"><div class="m" data-offset-y=25>Xp</div></td>
+ <td style="vertical-align: top"><div class="m" data-offset-y=0>Xp</div></td>
+ <td style="vertical-align: middle"><div class="m" data-offset-y=25>Xp</div></td>
+ <td style="vertical-align: bottom"><div class="m" data-offset-y=50>Xp</div></td>
+ <td style="vertical-align: baseline"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: sub"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: super"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: text-top"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: text-bottom"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: 100px"><div class="m" data-offset-y=28>Xp</div></td>
+ <td style="vertical-align: 100%"><div class="m" data-offset-y=28>Xp</div></td>
+</table>
+
+<p class="testdesc">All the baseline values.
+Same as test before, but use display:table/table-cell. Default td alignment is baseline, not middle.</p>
+<div style="height:100px;position:relative" class="ahem vgrad display-table">
+ <div class="display-cell" style="font: 75px/1 Ahem;vertical-align:baseline;"><div class="m" data-offset-y=0>Xp</div></div>
+ <div class="display-cell" style="" title="default"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: top"><div class="m" data-offset-y=0>Xp</div></div>
+ <div class="display-cell" style="vertical-align: middle"><div class="m" data-offset-y=25>Xp</div></div>
+ <div class="display-cell" style="vertical-align: bottom"><div class="m" data-offset-y=50>Xp</div></div>
+ <div class="display-cell" style="vertical-align: baseline"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: sub"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: super"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: text-top"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: text-bottom"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: 100px"><div class="m" data-offset-y=28>Xp</div></div>
+ <div class="display-cell" style="vertical-align: 100%"><div class="m" data-offset-y=28>Xp</div></div>
+</div>
+
+
+<p class="testdesc">Baselines with %ge children</p>
+<p class="error">FF/Edge fails here</p>
+<div>
+ inline table
+ <table style="height:100px;position:relative;display:inline-table">
+ <td style="vertical-align:baseline">
+ <div style="width:100px;height:50%;background:rgba(0,120,0, 0.5)" data-offset-y=30></div>
+ </td>
+ <td style="vertical-align:baseline">
+ <div style="width:100px;height:80%;background:rgba(0,120,0, 0.5)" data-offset-y=0></div>
+ </td>
+ </table>
+</div>
+<p class="testdesc">Baseline and td height
+If td is baseline aligned, and has a height, how tall should the td be?
+</p>
+<p class="error">Legacy/FF apply height to below baseline?. With baseline alignment, this makes the cell taller.</p>
+<table style="border: 1px solid black" data-expected-height=202>
+ <tr>
+ <td style="vertical-align:baseline;height:200px">base</td>
+ <td style="vertical-align:baseline">
+ <div style="background:yellow;width:50px;height:100px"></div>
+ </td>
+ </tr>
+</table>
+
+<p class="testdesc">Baseline of rowspanned cell
+rowspanned td's should contribute to baseline, but not to the row height.</p>
+<table class="ahem">
+ <tr data-expected-height=100>
+ <td style="vertical-align:baseline;height:100px;background-color:#DFD;">Xp</td>
+ <td style="vertical-align:baseline;font-size:40px;line-height:1.5" rowspan=2><div class="m">Xp</div><br>Xp<br>Xp</td>
+ </tr>
+ <tr data-expected-height=100>
+ <td style="vertical-align:baseline;height:100px">Xp</td>
+ </tr>
+</table>
+
+</main>
+<script>
+ checkLayout("table, .display-table");
+</script>
+
diff --git a/testing/web-platform/tests/css/css-tables/tentative/caption.html b/testing/web-platform/tests/css/css-tables/tentative/caption.html
new file mode 100644
index 0000000000..e733285901
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/caption.html
@@ -0,0 +1,137 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<title>caption</title>
+<meta name="flags" content="ahem">
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/tables.html#the-caption-element"/>
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#bounding-box-assignment" />
+<style>
+ main table {
+ border-spacing: 0 0;
+ position:relative;
+ background: gray;
+ }
+ main td {
+ background: #BFB;
+ }
+ main caption {
+ background: yellow;
+ }
+ main caption > div {
+ display: inline-block;
+ background: rgba(0,0,0,0.1);
+ }
+ main caption > div:after {
+ content: "c";
+ }
+ .lh {
+ line-height:30px;
+ }
+</style>
+<h1>Caption sizing and positioning</h1>
+<p class="error">There is a fundamental disagreement between Chrome Legacy and Firefox on caption size influence on table width. Chrome uses caption min width as lower limit of table's grid box, FF does not. Firefox also does not support multiple captions.</p>
+
+<main>
+
+<h2>Caption width limits</h2>
+
+<p class="testdesc">Caption minmax and grid width
+caption.min is lower limit of grid min.</p>
+<table>
+ <caption data-expected-width=50><div style="width:50px"></div><div style="width:30px"></caption>
+ <td data-expected-width=50>auto</td>
+</table>
+
+<p class="testdesc">Caption.min vs caption.css_width
+Caption.css_width is upper limit of caption.min
+Caption.css_width is lower limit of caption.min
+</p>
+<table>
+ <caption style="width:100px" data-expected-width=100><div style="width:200px"></div></caption>
+ <td data-expected-width=100>auto</td>
+</table>
+<table>
+ <caption style="width:300px" data-expected-width=300><div style="width:200px"></div></caption>
+ <td data-expected-width=300>auto</td>
+</table>
+
+
+<p class="testdesc">Caption width:50%
+Percent width is resolved wrt to table width.</p>
+<table style="width:200px">
+ <caption style="width:50%" data-expected-width=100><div></div></caption>
+ <td data-expected-width=200>auto</td>
+</table>
+
+<table style="width:200px">
+ <caption style="width:50%" data-expected-width=100><div style="width:200px"></div></caption>
+ <td data-expected-width=200>auto</td>
+</table>
+
+<p class="testdesc">Caption and size of empty table
+ Larger of table borders, and caption min size.</p>
+<table style="border:50px solid green;border-spacing:10px" data-expected-width=100>
+ <caption><div style="width:50px">c</div><div style="width:50px">c</div></caption>
+</table>
+
+<p class="testdesc">Caption height:80%
+github spec <a href="https://github.com/w3c/csswg-drafts/issues/4676">issue</a>.
+TablesNG will not resolve percentage heights per spec. FF agrees.
+</p>
+<table style="width:200px;height:100px">
+ <caption style="height:80%" data-expected-height=30><div style="height:30px"></div></caption>
+ <td data-expected-width=200>auto</td>
+</table>
+
+<p class="testdesc">Multiple captions
+Do we allow multiple captions? There are 4 in this test.</p>
+<table>
+ <caption class="lh" data-offset-y=0>over1</caption>
+ <caption class="lh" data-offset-y=30>over2</caption>
+ <caption class="lh" style="caption-side:bottom" data-offset-y=90>under1</caption>
+ <caption class="lh" style="caption-side:bottom" data-offset-y=120>under2</caption>
+ <td class="lh" data-offset-y=60>2 above me, 2 below me?</td>
+</table>
+<p class="testdesc">Caption margins
+Margins between captions do not collapse</p>
+<table style="width:200px">
+ <caption class="lh" style="margin:20px;" data-offset-y=20 data-offset-x=20>20px margins</caption>
+ <td data-expected-width=200 data-offset-y=70>1 caption</td>
+</table>
+<table style="width:200px">
+ <caption class="lh" style="margin:20px;" data-offset-y=20 data-offset-x=20>20px margins</caption>
+ <caption class="lh" style="margin:20px;" data-offset-y=90 data-offset-x=20>20px margins</caption>
+ <td data-expected-width=200 data-offset-y=140>2 captions</td>
+</table>
+
+
+<p class="testdesc">Caption margins auto
+auto margins center captions that are less wide than the table.
+</p>
+<table style="width:200px">
+ <caption class="lh" style="margin:auto" data-offset-x=0><div style="width:100px">auto margins</div></caption>
+ <td data-expected-width=200>1 caption</td>
+</table>
+<table style="width:200px">
+ <caption class="lh" style="margin:auto;width:50%" data-offset-x=50><div style="width:100px">auto margins</div></caption>
+ <td data-expected-width=200>1 caption</td>
+</table>
+
+
+<p class="testdesc">Vertical writing mode caption
+</p>
+<table>
+ <caption style="writing-mode:vertical-rl;height:min-content;font:10px Ahem;color:rgba(0,0,0,0.3)" data-expected-height=100 ><div style="height:100px;">vertical</div> caption bigger than table</caption>
+ <tbody data-offset-y=100>
+ <td>vertical!</td>
+ </tbody>
+</table>
+
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/col-collapse-table-size.html b/testing/web-platform/tests/css/css-tables/tentative/col-collapse-table-size.html
new file mode 100644
index 0000000000..a28a1e204a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/col-collapse-table-size.html
@@ -0,0 +1,88 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<title>col visibility:collapse and minmax sizes</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#visibility-collapse-track-rendering"/>
+
+<style>
+
+ main table {
+ right: 0;
+ display:inline-table;
+ border: 1px solid black;
+ }
+ main col {
+ visibility:collapse;
+ }
+ main td {
+ width: 200px;
+ height: 20px;
+ }
+ main caption {
+ background: yellow;
+ }
+ main td:nth-child(1) {
+ background: rgba(255,0,0,0.2);
+ }
+ main td:nth-child(2) {
+ background: rgba(200,200,200,1.0);
+ }
+ main table:hover col {
+ visibility: visible;
+ }
+</style>
+
+<h1>Interactions between &lt;COL&gt; visiblity:collapse, and table inline size</h1>
+<p>What happens to the table size when column collapses? Should the space taken up by the table
+ remain the same, but the table iteslf should shrink?</p>
+<p>Hovering over tables will turn off column collapsing</p>
+<main>
+
+<p style="position:absolute;top:200px;left:0;width: 300px">
+Tables to the right are absolutely positioned</p>
+<table id="abs" style="position:absolute;top:200px;right:0">
+ <col>
+ <td style="width:100px"></td>
+ <td>absolute, right:0</td>
+</table>
+
+ <table id="abscaption" style="position:absolute; top:260px;right:0" >
+ <col>
+ <caption style="width:250px">caption</caption>
+ <td></td>
+ <td>absolute, right:0</td>
+</table>
+
+<p style="margin-top:200px">Inline tables</p>
+<table id="caption">
+ <col>
+ <caption style="width:500px">caption</caption>
+ <td></td>
+ <td></td>
+</table><span style="font-size:50px">after</span>
+<p>
+
+<table id="plain">
+ <col>
+ <td style="width:100px">td</td>
+ <td></td>
+</table><span style="font-size:50px">after</span>
+
+<p>Table as a flex item</p>
+
+<div style="display:flex;width:700px">
+
+<table id="plain">
+ <col>
+ <td style="width:100px">td</td>
+ <td></td>
+</table>
+<div style="flex-grow:1;background-color:yellow">
+</div>
+</main>
+
+<script>
+ checkLayout("main table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/colgroup-col.html b/testing/web-platform/tests/css/css-tables/tentative/colgroup-col.html
new file mode 100644
index 0000000000..40fbefee20
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/colgroup-col.html
@@ -0,0 +1,122 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<title>COLGROUP/COL</title>
+<meta name="flags" content="ahem">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/tables.html#the-colgroup-element" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/tables.html#the-col-element" />
+<link rel="help" href="https://stackoverflow.com/questions/29411447/what-does-the-width-attribute-of-colgroup-actually-specify" />
+<style>
+ main table {
+ background: gray;
+ }
+
+ main td {
+ background: #BFB;
+ }
+
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+<main>
+<h1>Colgroup col widths</h1>
+<ol>
+ <li>colgroup's purpose is to "group" cols</li>
+ <li>one can think of colgroup as always generating max(colgroup.span,1) cols, unless it has &lt;col&gt; children.</li>
+ <li>colgroup css_width specifies width of generated cols.</li>
+ <li>col.css_width can override colgroup width</li>
+</ol>
+<p class="testdesc">colgroups with spans</p>
+<table>
+ <colgroup width="100px"></colgroup>
+ <colgroup width="100px" span=3></colgroup>
+ <td data-expected-width=100>cg1</td>
+ <td data-expected-width=100>cg2</td>
+ <td data-expected-width=100>cg2</td>
+ <td data-expected-width=100>cg2</td>
+ <td data-expected-width=50><div style="width:50px">50px</div></td>
+</table>
+
+<p class="testdesc">cols with spans</p>
+<table>
+ <col width="100px">
+ <col width="100px" span=3>
+ <td data-expected-width=100>col1</td>
+ <td data-expected-width=100>col2</td>
+ <td data-expected-width=100>col2</td>
+ <td data-expected-width=100>col2</td>
+ <td data-expected-width=50><div style="width:50px">50px</div></td>
+</table>
+
+<p class="testdesc">colgroups with cols</p>
+<table>
+ <colgroup span=4 style="width:100px">
+ <col>
+ <col style="width:50px">
+ <col style="width:150px">
+ </colgroup>
+ <td data-expected-width=100>cg</td>
+ <td data-expected-width=50>col1</td>
+ <td data-expected-width=150>col2</td>
+ <td data-expected-width=50><div style="width:50px">50px</div></td>
+</table>
+
+<p class="testdesc">colgroups with cols with spans</p>
+<p class="error">Legacy fails col with span inside colgroup test.</p>
+<table>
+ <colgroup span=3 style="width:100px">
+ <col>
+ <col style="width:50px" span=2>
+ </colgroup>
+ <colgroup style="width:66px">
+ <col span=2>
+ </colgroup>
+ <td data-expected-width=100>cg1</td>
+ <td data-expected-width=50>col1</td>
+ <td data-expected-width=50>col1</td>
+ <td data-expected-width=66>cg2</td>
+ <td data-expected-width=66>cg2</td>
+ <td data-expected-width=75><div style="width:75px">50px</div></td>
+</table>
+
+<p class="testdesc">0% cols are ignored</p>
+<table data-expected-width=106>
+ <colgroup>
+ <col style="width:0%">
+ <col style="width:0%">
+ </colgroup>
+ <tr>
+ <td data-expected-width=100>
+ <div><span style=" display: inline-block;word-break: break-word;font: 20px/1 Ahem">01234</span></div>
+ </td>
+ <td>
+ <div></div>
+ </td>
+ </tr>
+</table>
+<table data-expected-width=107>
+ <colgroup>
+ <col style="width:0%">
+ <col style="width:1%">
+ </colgroup>
+ <tr>
+ <td data-expected-width=100>
+ <div><span style=" display: inline-block;word-break: break-word;font: 20px/1 Ahem;">01234</span></div>
+ </td>
+ <td>
+ <div></div>
+ </td>
+ </tr>
+</table>
+
+</main>
+
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/colspan-redistribution.html b/testing/web-platform/tests/css/css-tables/tentative/colspan-redistribution.html
new file mode 100644
index 0000000000..3c4d57c142
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/colspan-redistribution.html
@@ -0,0 +1,621 @@
+<!doctype html>
+<title>COLSPAN redistribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns" />
+<style>
+ main table {
+ border-spacing: 8px 8px;
+ margin-top:8px;
+ background: gray;
+ }
+ main td {
+ background: #BFB;
+ font-size: 10px;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+<main>
+<h1>Colspan&gt;1 width redistribution</h1>
+<p>TD with colspan&gt;1 redistributes its min/max/percent widths to the spanned cells.</p>
+<p>Creating explainable tests with percentage cells is complicated. Cell's percentage cannot be observed directly, but must be inferred from td+table widths. Rules that govern relationship between table grid width and percentage cell width are:</p>
+<ol>
+ <li id="rule1"><span class="rule1">Rule#1</span>, Each percentage column sets the floor for maximum table width. That table width is column.min_width / column.percent * 100.<br> Ex: 20px wide column, with 20% width, implies that the entire table must be at least 100px wide.</li>
+ <li id="rule2"><span class="rule2">Rule#2</span>, Sum of all percentages, combined with sum of widths of all non-percentages sets the floor maximum table widths. <br>Let P% be sum of all percentages, and Fpx sum of widths of all non-percentage columns. Maximum table width = Fpx * (1 + (100-P%)/P%).<br>
+ Ex: if percentage columns are 20%, and non-percentage columns are 100px, implies that that 80% is at least 100px, and that the entire table is at least 125px.
+ </li>
+</ol>
+<h2>Test design</h2>
+<p>All examples have border-spacing:8, td.padding:0.</p>
+<p>Tests are mostly tables with 2 rows. 1st row are the columns, 2nd row is the colspan&gt;1 column being distributed. Most test's colspan&gt;1 cell colspan encloses all cells except the last one. Each test is accompanied by test description. Test description contains:</p>
+<ol>
+ <li>First line describes the test geometry: cell:css/min/max. C1:20%/20px means width:20%, intrinsic min width 20px. If max is omitted, min == max.</li>
+ <li>Second line describes algorithm being tested in detail</li>
+ <li>Third line describes computation that generates the result.</li>
+ <li class="error">Red paragraphs are major browser disagreements</li>
+</ol>
+
+<h2>Colspan&gt;1 cell's percentage distribution auto tables</h2>
+<p>Rules</p>
+<ul>
+ <li>Percentages can only be redistributed to non-percentage cells.</li>
+ <li>If percentage does not get redistributed, treat colspan&gt;1 cell width as Auto</li>
+ <li>If all columns are empty (no max width), redistribute percentage evenly.</li>
+</ul>
+
+<p class="testdesc">C0:10%/20px C1:10%/20px C2:auto
+No colspan&gt;1 cells, shows what table looks like without colspan&gt;1 cell distribution.
+Table width by rule#1, 20px/0.1(10%) + 4*8 => 232px. Excess table width is distributed to auto cell.</p>
+<table data-expected-width="232">
+ <tr>
+ <td style="width:10%"><div style="width:20px">x</div></td>
+ <td style="width:10%"><div style="width:20px">x</div></td>
+ <td>x</td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan&gt;1:40%/Auto C0:10%/20px C1:10%/20px C2:auto
+Percentage does not get redistributed because all columns are percentages.
+Table width by rule#1 same as previous example.</p>
+<table data-expected-width="232">
+ <tr>
+ <td style="width:10%" data-expected-width="20"><div style="width:20px">x</div></td>
+ <td style="width:10%"><div style="width:20px">x</div></td>
+ <td>x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:40%">40%</td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan&gt;1:20%/100px C0:Auto/0 C1:Auto/0 C2:Auto/Auto
+Percentage gets redistributed evenly to empty cells.
+Each cell gets 10%, then (100-8)/2=>46px min width. Table min width is 46/0.1(10%) + 4*8 => 460 + 32 => 492</p>
+<p class="error">Chrome Legacy is wrong, 1st span cell gets all the width. FF/Edge agree.</p>
+<table data-expected-width="492">
+ <tr>
+ <td data-expected-width="46"></td>
+ <td></td>
+ <td>x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:20%"><div style="width:100px">100px</div></td>
+</table>
+
+<p class="testdesc">Colspan&gt;1: 19%/200px colspan&gt;1 cell, C0: 20%.20px, C1: 80px/80px
+Percentage is not getting redistributed, because column% > colspan&gt;1%</p>
+<table data-expected-width="224">
+ <tr>
+ <td style="width:20%" data-expected-width="40"><div style="width:20px">20</div></td>
+ <td style="width:80px" data-expected-width="160"><div style="width:80px">80</div></td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:19%" data-expected-width="208"><div style="width:208px">208</div></td>
+ </tr>
+</table>
+
+<h2>Colspan&gt;1 cell's percentage distribution fixed tables</h2>
+<p>Colspan cells distribute width over col widths.
+<p>Rules</p>
+<ul>
+ <li>Percentages are not distributed to fixed columns.</li>
+ <li>Percentages are not distributed to percentage columns.</li>
+ <li>Percentages are distributed to auto columns, each column gets distributed%/colspan percent.</li>
+</ul>
+<p class="testdesc">Auto column distribution
+auto colums get percentage widths distributed evenly.
+C0/C1 become 25% columns.
+Assignable table size is 400-4*8=368. Column size is 25% of 368 = 92px</p>
+<p class="error">FF disagrees in how border-spacing is handled and ends up with slightly different cell widths. </p>
+<table style="table-layout:fixed; width: 400px">
+ <col style="width:auto">
+ <col style="width:auto">
+ <tr>
+ <td colspan="2" style="width:50%">50%</td>
+ <td>a</td>
+ </tr>
+ <tr>
+ <td data-expected-width=92>a</td>
+ <td data-expected-width=92>aa</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<p class="testdesc">Fixed column distribution
+fixed columns do not get percentage distribution.</p>
+<table style="table-layout:fixed; width: 400px">
+ <col style="width:50px">
+ <col style="width:50px">
+ <tr>
+ <td colspan="2" style="width:50%">50%</td>
+ <td>a</td>
+ </tr>
+ <tr>
+ <td data-expected-width="50">a</td>
+ <td data-expected-width="50">a</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<p class="testdesc">Percentage column distribution
+percentage columns do not get percentage distribution.</p>
+<table style="table-layout:fixed; width: 400px">
+ <col style="width:12.5%">
+ <col style="width:25%">
+ <tr>
+ <td colspan="2" style="width:50%">50%</td>
+ <td>a</td>
+ </tr>
+ <tr>
+ <td data-expected-width="46">a</td>
+ <td data-expected-width="92">a</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<p class="testdesc">Distribute over percentage/auto/fixed mix cells
+Collspanned TD distributes 50%. Auto TD gets 50%/(colspanned span = 4): 12.5%
+12.5%* 400px is 50.
+</p>
+<table style="table-layout:fixed; width: 400px;border-spacing:0">
+ <col style="width:25%">
+ <col style="width:25px">
+ <col style="width:25px">
+ <col style="width:auto">
+ <tr>
+ <td colspan="4" style="width:50%">50%</td>
+ <td>a</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>a</td>
+ <td>a</td>
+ <td data-expected-width="50" style="background-color:yellow">a</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<h2>Colspan&gt;1 cell's minimum width distribution</h2>
+<h3>All unconstrained columns</h3>
+
+<p class="testdesc">Colspan&gt;1: Auto/300px C0:Auto/75pxpx C1:Auto:25px; C2:20px/Auto
+Basic distribution over auto columns, cells grow evenly.
+Distribute 300-8=292 proportional to maxwidth. C0 gets 75/100*292=219.</p>
+<table data-expected-width="344">
+ <tr>
+ <td data-expected-width="219"><div style="width:75px">75px</div></td>
+ <td><div style="width:25px">25px</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td data-expected-width="300" colspan=2><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan&gt;1: 260px/300px C0:Auto/100px C1:Auto/100px C2:Auto/Auto
+Colspan&gt;1 cell min width wins over css width.
+Table width same as previous example.</p>
+<table data-expected-width="344">
+ <tr>
+ <td data-expected-width="146"><div style="width:100px">100px</div></td>
+ <td><div style="width:100px">100px</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td data-expected-width="300" colspan=2 style="width:260px"><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<h3>All fixed columns</h3>
+<li>column gets min_width proportional to its max width.
+
+<p 7 class="testdesc">Colspan&gt;1: 260/300 C0:100/50/100 C1:100/100 C2:20/Auto
+Distribute surplus proportional to max width.
+Colspan&gt;1 is distributing 292, surplus 92, each column gets 46.
+</p>
+<table data-expected-width="344">
+ <tr>
+ <td style="width:100px" data-expected-width="146"><div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td style="width:100px"><div style="width:100px">100px</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td data-expected-width="300" colspan=2 style="width:260px"><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<p 8 class="testdesc">Colspan&gt;1: 300/300 C0:100/25 C1:100/75 C2:20/Auto
+Column minimum width is less than its CSS width.
+Just like last example, both columns get 46.
+<table data-expected-width="334" style="width:1px">
+ <tr>
+ <td style="width:100px" data-expected-width="146"><div style="width:25px">25px</div></td>
+ <td style="width:100px"><div style="width:75px">75px</div></td>
+ <td style="width:20px"><div style="width:10px">x</div></td>
+ </tr>
+ <tr>
+ <td data-expected-width="300" colspan=2 style=""><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan&gt;1: 300/300 C0:20/100 C1:100/75 C2:20/Auto
+First column's min width > css width.
+Like last example, each column minimum width increases in proportion to the max.</p>
+<p class="error">Chrome differs from FF/Edge. It distributes min-width in proportion to css width, not max width</p>
+<table data-expected-width="344">
+ <tr>
+ <td style="width:20px" data-expected-width="146"><div style="width:100px">20/100px</div></td>
+ <td style="width:40px"><div style="width:100px">40/100px</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td data-expected-width="300" colspan=2 style=""><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<h3>All percent columns</h3>
+ <ul>
+ <li>min width never gets smaller than it started.
+ <li>min width becomes cell.percent/cells.percent * colspan&gt;1_cell.min_width</li>
+ <li>max width becomes cell.percent/cells.percent * colspan&gt;1_cell.max_width</li>
+ </ul>
+
+<p 10 class="testdesc">Colspan&gt;1:Auto/300px C0:25%/50 C1:25%/30 C2:20/Auto
+Colspan&gt;1 min width gets distributed proportional to percentage (not min/max width).
+Columns get min_width = 146, causes table width of 146/0.25 + 4*8 = 616.
+<table data-expected-width="616">
+ <tr>
+ <td style="width:25%" data-expected-width="146"><div style="width:50px">25%/50</div></td>
+ <td style="width:25%"><div style="width:30px">25%/30</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style=""><div style="width:300px">300px min</div></td>
+ </tr>
+</table>
+
+<p 11 class="testdesc">Colspan&gt;1:Auto/400px C0:20%/50 C1:60%/50 C2:20/Auto.
+Colspan&gt;1 min width gets distributed proportional to percentage (not min/max width).
+Cells get 98/294, table by rule#1 98px/0.2 + 32 = 522</p>
+<p class="error">Edge disagrees, table is 870</p>
+<div style="width:600px">
+<table data-expected-width="522">
+ <tr>
+ <td style="width:20%" data-expected-width="98"><div style="width:50px">20%/50px</div></td>
+ <td style="width:60%" data-expected-width="294"><div style="width:50px">60%/50px</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style=""><div style="width:400px">400px min</div></td>
+ </tr>
+</table>
+</div>
+
+<p 12 class="testdesc">Colspan&gt;1:Auto/468 C0:50%/150 C1:30%/150 C2:20/Auto
+This tests conflict resolution where min-width > redistributed min width.
+Colspanned redistribution: distributed 468-8 = 460 over C0/C1
+Colspanned 468px needs to distribute 460px over C0/C1.
+C0 percent size is 50% * 460 = 230
+C1 percent size is 30% * 460 = 138, defaults to min size of 150
+Column 1 size is 230 + 50%/80% * 80 = 280px
+Column 2 size is 150 + 30%/80% * 80 = 180px
+Column 3 remains 20px
+Assignable table inline size
+C1 dominates estimate: 180/30% + 4*8 = 632
+Compute final column widths from assignable table size:
+C0 = 50% of 600 = 300 C1 = 30% of 600 = 180 , C2 gets the remaining 120</p>
+<table data-expected-width="632">
+ <tr>
+ <td style="width:50%" data-expected-width="300"><div style="width:150px">50%/150px</div></td>
+ <td style="width:30%" data-expected-width="180"><div style="width:150px">30%/150px</div></td>
+ <td style="width:20px" data-expected-width="120">x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style=""><div style="width:468px">408px min</div></td>
+ </tr>
+</table>
+
+
+<p 13 class="testdesc"> Colspan&gt;1:Auto/400px C0:50%/75px/125px, C1:30%/75px/125px C2:20px/Auto
+Colspan&gt;1 cell distribution over different percentages.
+400-8px min width gets redistributed as 245/147 (no min width limits)
+</p>
+<p class="error">Edge is different, table is 685 instead of 522.</p>
+<table data-expected-width="522">
+ <tr>
+ <td style="width:50%" data-expected-width="245"><div style="width:75px">50%/75</div><div style="width:50px">/125</div></td>
+ <td style="width:30%" data-expected-width="147"><div style="width:75px">30%/75</div><div style="width:50px">/125</div></td>
+ <td style="width:20px">x</td>
+ </tr>
+ <tr>
+ <td colspan=2 style=""><div style="width:400px">400px min</div></td>
+ </tr>
+</table>
+
+<h3>Auto/fixed mix columns</h3>
+<p class="testdesc">Colspan&gt;1: Auto/500; C0: Auto/40 C1:150/100
+Colspan&gt;1 excess min: 500-140-8=352; excess max: 500-190-8=302
+Initial min/max C0:40/40, C1:100/150
+Excess is distributed to Auto C0:392/342, C1:100/150
+Assignable width is 492. C0 gets 342, C1 get max:150
+Chrome Legacy does something very different to arrive at the same answer.
+Initial min/max is the same.
+Min gets distributed to C0 and C1 in proportion to max_width: C0:342/40 C1:150/150,
+Min also gets clamped to css width. This is the key difference betweeen NG
+and Legacy code. NG cannot clamp to css width, because it is not available.
+Max gets distributed to both in proportion to max_width: C0:342/103 C1:150/389
+Assignable table width is: 492 (sum of min), min gets used as final width.
+
+Analysis: colspan&gt;1 cell distribution over fixed/auto.
+Legacy incorrectly distributes minmax over both fixed and auto cells
+in proportion to max width,and clamps min to css width.
+
+This width becomes final width for auto tables without any further distribution.
+FF distributes min only over auto, and max over auto.
+Final distribution uses Guess 2 rules: start off with Auto(min), Fixed(max),
+distribute excess to Auto. Ends up with the same result as Legacy.</p>
+<table data-expected-width=516>
+ <tr>
+ <td data-expected-width=342>
+ <div style="width:40px">Auto</div></td>
+ <td style="width:150px" data-expected-width=150>
+ <div style="width:100px">150</div></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <div style="width:500px">500</div></td>
+ </tr>
+</table>
+<p class="testdesc">C0:70/Auto C1:70/Auto C2:Auto/50
+This testcase demonstrates how Legacy Chrome handling of min widths is broken.
+There are 2 fixed columns, and 1 auto. The width of fixed columns should be
+the same, but is not. The problem happens when min-width of fixed columns is
+less than fixed width, and there are auto columns.</p>
+
+<p class="error">Chrome Legacy incorrectly assigns minimum width to C0/C1
+to css width of 70. It does compute assignable table width correctly
+as 166 px. This violates the invariant:
+assignable table width >= sum of min widths.
+Chrome resolves invariant violation by truncating one fixed width column
+below its minimum width. </p>
+<table style="width:1px" data-expected-width=166>
+ <tr>
+ <td style="width:70px" data-expected-width=42>0</td>
+ <td style="width:70px" data-expected-width=42>0</td>
+ <td data-expected-width=50><div style="width:50px" >50</div></td>
+ </tr>
+ <tr>
+ <td colspan=3 ><div style="width:150px"></div>
+ </td>
+ </tr>
+</table>
+
+<h3>Percentage/fixed mix columns</h3>
+<p>The Legacy code that deals with this is confusing, it tries to redistribute minimum width in proportion to max width, unless there are auto cells. All the browsers disagree on final widths. Some things everyone agrees on:
+ <li>if there are auto cells, fixed cells do not grow.</li>
+</p>
+
+<p class="testdesc">Colspan&gt;1:N/A C0:60%/100 C2:100/100
+An example what table looks like without colspan&gt;1 distribution.
+Table width by rule#2: (60/(100-60) +1) * 100 = 250 + 24 = 274</p>
+<table data-expected-width="274">
+ <tr>
+ <td data-expected-width="150" style="width:60%"><div style="width:100px">60%</div></td>
+ <td data-expected-width="100" style="width:100px"><div style="width:100px">100px</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan&gt;1:N/A C0:50%/100 C1:50%/100 C2:100/100
+Total column percent is 100%, forcing maximum table grid width by rule #2 to infinity.
+Table css width is 1px, overriding grid max width.
+Final column width is column's minimum width.
+</p>
+<div style="width:500px">
+ <table style="width:1px">
+ <tr>
+ <td data-expected-width="100" style="width:50%"><div style="width:100px">50%</div></td>
+ <td data-expected-width="100" style="width:50%"><div style="width:100px">50%</div></td>
+ <td data-expected-width="100" style="width:100px"><div style="width:100px">100px</div></td>
+ </tr>
+ </table>
+</div>
+
+<p class="testdesc">Colspan&gt;1:N/A C0:50%/100 C1:50%/100 C2:100/100
+Same example as above, but table width is auto.
+Table grows to size of containing block.</p>
+<div style="width:500px">
+ <table>
+ <tr>
+ <td data-expected-width="184" style="width:50%"><div style="width:100px">50%</div></td>
+ <td data-expected-width="184" style="width:50%"><div style="width:100px">50%</div></td>
+ <td data-expected-width="100" style="width:100px"><div style="width:100px">100px</div></td>
+ </tr>
+ </table>
+</div>
+
+<p class="testdesc">Colspan&gt;1: Auto/200px C0:40%/20 C1:50/50 C2:100/20
+Table css width is 1px. This forces grid minimum.
+FF: %ge cell gets its percentage width resolved wrt distributing cell.
+fixed cells get remaining excess width redistributed in proportion
+to max size.
+Chrome algorithm: distributes proportionally to min_width. The problem with
+this is that 40% cell will end up with 0 if no min width.
+<p class="error">Edge distributes all the width to the %ge cell, Chrome distributes proportionally to min width. </p>
+<table style="width:1px" data-expected-width="252">
+ <tr>
+ <td style="width:40%" data-expected-width=80><div style="width:20px">40%</div></td>
+ <td style="width:50px" data-expected-width=120><div style="width:50px">50</div></td>
+ <td data-expected-width="20" style="width:100px"><div style="width:20px">20</div></td>
+ </tr>
+ <tr>
+ <td colspan=2 data-expected-width="208" ><div style="width:208px">208px min</div></td>
+ </tr>
+</table>
+
+<h2>Colspan&gt;1 cell's maximum width distribution</h2>
+<li>Only constrained colspans can distribute max-width over fixed columns</li>
+
+<p class="testdesc">Colspan: constrained. Col: constrained
+Constrained colspan redistributes widths over constrained cols.
+</p>
+<table data-expected-width=216>
+ <col style="width:50px">
+ <col style="width:50px">
+ <tr>
+ <td>50</td>
+ <td>50</td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:200px" data-expected-width=200>200</td>
+ </tr>
+</table>
+<p class="testdesc">Colspan: unconstrained. Col: constrained
+Colspan max-width does not get redistributed.
+</p>
+<table data-expected-width=124>
+ <col style="width:50px">
+ <col style="width:50px">
+ <tr>
+ <td>50</td>
+ <td>50</td>
+ </tr>
+ <tr>
+ <td colspan=2 data-expected-width=108><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Colspan: unconstrained, Col: constrained/%
+Colspanned col distributes width over %ge column.
+max-guess is 50px + 200px*50% = 150px
+distributable_size is 50px
+%ge column gets percentage_size + distributable_size = 150px
+Later, this makes table 300px wide.
+</p>
+<p class="error">FF, Legacy, and TablesNG all disagree about the correct widths. FF feels more like the right answer, but I can't figure out the math behind it.</p>
+<table data-expected-width=308>
+ <col style="width:50px">
+ <col style="width:50%">
+ <tr>
+ <td data-expected-width=142>50</td>
+ <td>50</td>
+ </tr>
+ <tr>
+ <td colspan=2 data-expected-width=292><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<h2>Merging cell widths into column widths</h2>
+<p>What happens when different types of cells get merged into a single column?</p>
+<p class="testdesc">C0:0 25%/50px C0:1 50%/40px
+C0:0 alone would imply table width of 50/.25 = 200px.
+C0:1 alone would imply table width of 40/.5 = 80px.
+But, largest percentage and largest min width win, so the table width is 50/.5 = 100px.
+</p>
+<table data-expected-width=124>
+ <tr>
+ <td style="width:25%" data-expected-width=50>
+ <div style="width:50px">25%/50px</div></td>
+ <td data-expected-width=50>Auto</td>
+ </tr>
+ <tr>
+ <td style="width:50%">
+ <div style="width:40px">50%/40</div></td>
+ <td>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">Merging fixed and percentage
+Column that contains both percent and fixed cells is treated as percent.
+<table data-expected-width=632>
+ <tr>
+ <td style="width:25%" data-expected-width=150>
+ <div style="width:100px" >25%/100</div></td>
+ <td style="width:50px" data-expected-width=50>50px fixed</td>
+ <td>auto</td>
+ </tr>
+ <tr>
+ <td style="width:150px">150</td>
+ <td>Auto</td>
+ <td>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">Order of colspan&gt;1 cell redistribution
+Initial minmax of all cells is 50px.
+C0:1 redistributes 200
+C1:2 redistributes 400
+Chrome distributes right-to-left:
+C1:2 distributes 400, and C1 and C2 both get 200
+When C0:1 turns come, C0+C1 are already long enough, nothing to distirbute
+<p class="error">
+In testcase /tables/mozilla_expected_failures/core/col_span2.html
+distribution right-to-left is described as a bug.
+Firefox and Edge both distribute left to right.
+Chrome is only one that distributes right to left.
+Firefox distribution is not cumulative, it uses original minmax to compute final widths. Edge agrees with TablesNG.
+But, mozilla is stable for row reordering.</p>
+</p>
+<table data-expected-width=532>
+ <tr>
+ <td colspan=2><div style="width:208px">200</div></td>
+ <td><div style="width:50px">50</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:50px">50</div></td>
+ <td colspan=2><div style="width:408px">400</div></td>
+ </tr>
+ <tr>
+ <td data-expected-width=100>Auto</td>
+ <td data-expected-width=267><div style="width:50px">Auto</div></td>
+ <td data-expected-width=133>Auto</td>
+ </tr>
+</table>
+<table data-expected-width=482>
+ <tr>
+ <td colspan=2><div style="width:408px">400</div></td>
+ <td><div style="width:50px">50</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:50px">50</div></td>
+ <td colspan=2><div style="width:208px">200</div></td>
+ </tr>
+ <tr>
+ <td data-expected-width=200>Auto</td>
+ <td data-expected-width=200><div style="width:50px">Auto</div></td>
+ <td data-expected-width=50>Auto</td>
+ </tr>
+</table>
+<p class="testdesc">Order of colspan&gt;1 cell redistribution
+Similar to previous testcase, but colspan is 3, not 2.</p>
+<p class="error">
+In testcase /tables/mozilla_expected_failures/core/col_span2.html
+distribution right-to-left is described as a bug.
+Firefox and Edge both distribute left to right.
+TablesNG matches Edge/FF.</p>
+</p>
+<table data-expected-width=740>
+ <tr>
+ <td colspan=3><div style="width:316px">300</div></td>
+ <td><div style="width:50px">50</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:50px">50</div></td>
+ <td colspan=3><div style="width:616px">600</div></td>
+ </tr>
+ <tr>
+ <td data-expected-width=100>Auto</td>
+ <td data-expected-width=240><div style="width:50px">Auto</div></td>
+ <td data-expected-width=240><div style="width:50px">Auto</div></td>
+ <td data-expected-width=120>Auto</td>
+ </tr>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/column-widths.html b/testing/web-platform/tests/css/css-tables/tentative/column-widths.html
new file mode 100644
index 0000000000..b151c2263b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/column-widths.html
@@ -0,0 +1,300 @@
+<!doctype html>
+<title>Column widths</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns" />
+<style>
+ main table {
+ background: gray;
+ border-spacing: 8px 8px;
+ table-layout: auto;
+ margin-top: 4px;
+ }
+ main td {
+ background: #BFB;
+ font-size: 10px;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+<main>
+<h1>Col width</h1>
+<p>how does col width interact with td widths to produce final column width?</p>
+<p>Inputs are colgroup/col widths, and td widths.
+<p>td widths merge, then merge again with col to produce column widths.
+<p>Output is column min/max/percent w0dths.
+<p>Colgroup/col has css min_width, css max_width, css percent.</p>
+<p>TD has intrinsic minmax, css width, css percent width, css max width, css min width</p>
+
+<h2>Initial cell assignment</h2>
+
+
+<p class="testdesc">Unconstrained single TD, table-layout:auto
+td.min = minmax.min
+td.max = minmax.max</p>
+<table style="width:1px" data-expected-width=266>
+ <tr>
+ <td><div style="width:50px">min</div><div style="width:250px">min</div></td>
+ </tr>
+</table>
+<table data-expected-width=316>
+ <tr>
+ <td><div style="width:50px">max</div><div style="width:250px">max</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Unconstrained single TD, table-layout:fixed
+td.min = 0
+td.max = minmax.max</p>
+<table style="width:1px;table-layout:fixed" data-expected-width=16>
+ <tr>
+ <td><div style="width:50px">min</div><div style="width:250px">min</div></td>
+ </tr>
+</table>
+<table style="table-layout:fixed;width:300px" data-expected-width=300>
+ <tr>
+ <td><div style="width:50px">max</div><div style="width:250px">max</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Constrained single TD, table-layout:auto
+ td.min = minmax.min
+ td.max = max(minmax.min, css.width)
+</p>
+<table data-expected-width=266>
+ <tr>
+ <td style="width:200px"><div style="width:50px">max</div><div style="width:250px">max</div></td>
+ </tr>
+</table>
+<table data-expected-width=416>
+ <tr>
+ <td style="width:400px"><div style="width:50px">max</div><div style="width:250px">max</div></td>
+ </tr>
+</table>
+<table style="width:1px" data-expected-width=26>
+ <tr>
+ <td style="width:50px"><div style="width:10px">min</div></td>
+ </tr>
+</table>
+<table data-expected-width=266>
+ <tr>
+ <td style="width:100px"><div style="width:50px">min</div><div style="width:250px">min</div></td>
+ </tr>
+</table>
+<table data-expected-width=416>
+ <tr>
+ <td style="width:400px"><div style="width:50px">min</div><div style="width:250px">min</div></td>
+ </tr>
+</table>
+
+
+<h2>TD/TD merging</h2>
+
+<p>TD merging only happens in auto, in fixed only 1st row gets measured</p>
+
+<p class="testdesc">Two unconstrained TDs, table-layout:auto or fixed
+ td.min = max(C0.min, C1.min). always 0 in fixed layout.
+ td.max = max(C0.max, C1.max)
+</p>
+<table data-expected-width=316>
+ <tr>
+ <td data-expected-width=300><div style="width:50px">auto</div><div style="width:250px">max</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:100px">auto</div><div style="width:150px">auto</div></td>
+ </tr>
+</table>
+<table style="width:1px" data-expected-width=266>
+ <tr>
+ <td data-expected-width=250><div style="width:50px">auto</div><div style="width:250px">max</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:100px">auto</div><div style="width:150px">auto</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Unconstrained (UN) and constrained (CON) TD
+ td.min = max(UN.min, CON.min)
+ td.max = max(UN.min, CON.max)
+</p>
+<p class="error">Chrome Legacy and Edge fail this test. They do not limit unconstrained maximum: td.max = max(UN.max, CON.max).</p>
+<table style="width:1px" data-expected-width=36>
+ <tr>
+ <td style="width:50px" data-expected-width=20><div style="width:20px">min</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:15px">min</div></td>
+ </tr>
+</table>
+<table data-expected-width=66>
+ <tr>
+ <td style="width:50px" data-expected-width=50><div style="width:20px">max</div></td>
+ </tr>
+ <tr>
+ <td><div style="width:40px">max</div><div style="width:40px">max</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Two percent TDs
+ td.percent = max(C1.percent, C2.percent)
+ td.max = max(C1.max, C2.max)
+ td.min = max(C1.min, C2.min)
+</p>
+<table data-expected-width=324>
+ <tr>
+ <td style="width:10%"><div style="width:60px">60</div></td>
+ <td>auto</td>
+</tr>
+<tr>
+ <td style="width:20%" data-expected-width=60><div style="width:50px">50</div></td>
+ <td data-expected-width=240>auto</td>
+</tr>
+</table>
+
+<h2>COL/TD merging</h2>
+
+<p class="testdesc">col auto td auto
+column.min = td.min
+column.max = td.max</p>
+<table data-expected-width=66>
+ <col>
+ <td><div style="width:50px">auto</div></td>
+</table>
+
+<p class="testdesc">col fixed td auto
+ column.min = td.min
+ column.max = max(col[px], td.min)
+</p>
+<table data-expected-width=116>
+ <col style="width:100px">
+ <td><div style="width:50px">auto</div></td>
+</table>
+<table data-expected-width=126>
+ <col style="width:100px">
+ <td><div style="width:110px">110</div><div style="width:110px">110</div></td>
+</table>
+<table style="width:1px" data-expected-width=66>
+ <col style="width:100px">
+ <td><div style="width:50px">min</div></td>
+</table>
+
+<p class="testdesc">col % td auto
+column.min = td.min
+column.max = max(td.max, col.max)
+column.percent = col[%]
+<table data-expected-width=224>
+ <col style="width:80%">
+ <td><div style="width:50px">auto</div></td>
+ <td style="width:40px">40</td>
+</table>
+<table style="width:1px" data-expected-width=94>
+ <col style="width:80%">
+ <td style="width:50px"><div style="width:30px">auto</div></td>
+ <td><div style="width:40px"></div></td>
+</table>
+<table data-expected-width=274>
+ <col style="width:80%">
+ <td><div style="width:200px" data-expected-width=200>auto</div></td>
+ <td style="width:30px"><div style="width:30px">30</div></td>
+</table>
+
+<p class="testdesc">col auto td percent
+column.min = td.min
+column.max = td.max
+column.percent = td.percent
+<table data-expected-width=174>
+ <col>
+ <td style="width:80%" data-expected-width=120><div style="width:100px">auto</div></td>
+ <td ><div style="width:30px">10</div></td>
+</table>
+
+<p class="testdesc">col fixed td percent
+column.min = td.min
+column.max = max(td.max, col.max)
+column.percent = td.percent
+<table data-expected-width=424>
+ <col style="width:200px">
+ <td style="width:50%" data-expected-width=200><div style="width:50px">50</div></td>
+ <td><div style="width:50px">50</div>
+</table>
+<table style="width:1px" data-expected-width=124>
+ <col style="width:200px">
+ <td style="width:60%" data-expected-width=50><div style="width:50px">50</div></td>
+ <td><div style="width:50px">50</div>
+</table>
+
+<p class="testdesc">col percent td percent
+column.min = td.min
+column.max = max(td.max, col.max)
+column.percent = max(td.percent, col.percent)</p>
+<table data-expected-width=524>
+ <col style="width:60%">
+ <td style="width:50%" data-expected-width=300><div style="width:100px">100</div></td>
+ <td><div style="width:200px">200</div></td>
+</table>
+<table data-expected-width=524>
+ <col style="width:50%">
+ <td style="width:60%" data-expected-width=300><div style="width:100px">100</div></td>
+ <td><div style="width:200px">200</div></td>
+</table>
+
+<p class="testdesc">col auto td fixed
+column.min = td.min
+column.max = td.max</p>
+<table data-expected-width=116>
+ <col>
+ <td style="width:100px">100</td>
+</table>
+
+<p class="testdesc">col fixed td fixed
+column.min = td.min
+column.max = max(td.max, col.max)</p>
+<table data-expected-width=216>
+ <col style="width:200px">
+ <td style="width:100px">100</td>
+</table>
+<table data-expected-width=216>
+ <col style="width:100px">
+ <td style="width:200px">100</td>
+</table>
+
+<p class="testdesc">col percent td fixed
+column.min = td.min
+column.percent = col.percent
+column.max = max(td.max, col.max)</p>
+<table data-expected-width=424>
+ <col style="width:50%">
+ <td style="width:100px" data-expected-width=200>100</td>
+ <td><div style="width:200px">200</div>
+</table>
+
+<table style="width:1px" data-expected-width=234>
+ <col style="width:50%">
+ <td style="width:100px" data-expected-width=10><div style="width:10px">10</div></td>
+ <td><div style="width:200px">200</div></td>
+</table>
+
+<p class="testdesc">col fixed td fixed inside table-layout:fixed
+constrained columns take precedence in fixed layout.
+<table style="width:324px;table-layout:fixed" data-expected-width=324>
+ <col style="width:100px">
+ <td style="width:200px" data-expected-width=100>100</td>
+ <td data-expected-width=200><div style="width:400px" >200</div></td>
+</table>
+
+<p class="testdesc">col percent td fixed inside table-layout:fixed
+constrained columns take precedence in fixed layout.
+<table style="width:324px;table-layout:fixed" data-expected-width=324>
+ <col style="width:50%">
+ <td style="width:200px" data-expected-width=150>150</td>
+ <td><div style="width:400px">150</div></td>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/element-sizing.html b/testing/web-platform/tests/css/css-tables/tentative/element-sizing.html
new file mode 100644
index 0000000000..77e153ce3a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/element-sizing.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<title>TABLE fragment sizes</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/" />
+
+<main>
+<h1>TBODY/TR Element sizes and border spacing</h1>
+<p>Legacy Chrome:TR includes start/end, not before/after. 1st TBODY includes before/after, 2nd TBODY includes only after, not before.</p>
+<p>Firefox: TR/TBODY do not include start/end before/after.</p>
+<p>Proposal: match firefox</p>
+
+<table style="width:100px;border-spacing:10px;background:#ddd">
+ <tbody data-expected-width=80>
+ <tr data-expected-width=80>
+ <td data-expected-width=80>0,0</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>TR width is used for TD's percentage resolution</p>
+<table style="width:120px;border-spacing:10px;background:#ddd">
+ <tbody data-expected-width=100>
+ <tr data-expected-width=100>
+ <td style="padding:30%" data-expected-width=100 ><div data-offset-x=30>0,0</div></td>
+ </tr>
+ </tbody>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed-ref.html
new file mode 100644
index 0000000000..b3b1ce9ff3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed-ref.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(90deg, orange 0px, orange 10px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 170px, blue 170px);
+ background-repeat: no-repeat;
+ background-size: 50px 200px;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+ .td {
+ width: 50px;
+ height: 50px;
+ position:absolute;
+ }
+</style>
+
+<main>
+<div style="position: relative;border: 10px solid transparent; width:210px; height: 210px">
+ <div class="td bg" style="top:-5px;left:-5px;height:200px"></div>
+ <div class="td bg" style="top:-5px;left:45px;height:200px"></div>
+ <div class="td" style="background:var(--peek); height:100px; left:95px;top:45px"></div>
+ <div class="td bg" style="top:-5px;left:145px;height:200px;width:100px;background-size: 100px 200px"></div>
+</div>
+
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed.html
new file mode 100644
index 0000000000..6e6ae7a82c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-collapsed.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<title>Table collapsed column background image geometry</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#drawing-backgrounds-and-borders" />
+<link rel="match" href="background-image-column-collapsed-ref.html" />
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(90deg, orange 0px, orange 10px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 170px, blue 170px);
+ background-repeat: no-repeat;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+ main table {
+ border-spacing: 10px;
+ border: 10px solid transparent;
+ padding: 10px;
+ border-collapse: collapse;
+ }
+ main table:hover {
+ border: 10px solid yellow;
+ }
+ main td {
+ width: 50px;
+ height: 50px;
+ padding: 0px;
+ }
+</style>
+<body>
+<main>
+ <table>
+ <col class="bg">
+ <col class="bg">
+ <col>
+ <colgroup class="bg" span="2">
+ <tr>
+ <td rowspan=4></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td rowspan=2 colspan=2></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+</main>
+</body>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-ref.html
new file mode 100644
index 0000000000..5b04f0074c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column-ref.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 10px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 220px, blue 220px);
+ background-repeat: no-repeat;
+ background-size: 50px 230px;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+ .td {
+ width: 50px;
+ height: 50px;
+ position:absolute;
+ border: 4px solid black;
+ }
+</style>
+
+<main>
+<div style="position: relative;border: 10px solid yellow; width:290px; height: 290px">
+ <!-- row 1 -->
+ <div class="td bg" style="top:20px;left:20px;height:230px"></div>
+ <div class="td bg" style="top:20px;left:80px;"></div>
+ <div class="td" style="top:20px; left: 140px;"></div>
+ <div class="td" style="top:20px; left: 200px;"></div>
+ <!-- row 2
+ additional -4 offsets on background-position are for borders.
+ columns do not have borders.
+ -->
+ <div class="td bg" style="top:80px;left:80px;width:110px;height:110px;background-position-y:-64px;background-position-x:-4px"></div>
+ <div class="td" style="top:80px; left: 200px;"></div>
+ <!-- row 3 -->
+ <div class="td" style="top:140px; left: 200px;"></div>
+ <!-- row 4 -->
+ <div class="td bg" style="top:200px;left:80px;background-position-y:-180px"></div>
+ <div class="td" style="top:200px; left: 140px;"></div>
+ <div class="td" style="top:200px; left: 200px;"></div>
+</div>
+
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column.html
new file mode 100644
index 0000000000..c795aac5ea
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-column.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>Table column background image geometry</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#drawing-backgrounds-and-borders" />
+<link rel="match" href="background-image-column-ref.html" />
+<meta name="assert" content="Column backgrounds get painted into cells with correct geometry.">
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 10px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 220px, blue 220px);
+ background-repeat: no-repeat;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+ main table {
+ border-spacing: 10px;
+ border: 10px solid yellow;
+ padding: 10px;
+ }
+ main td {
+ width: 50px;
+ height: 50px;
+ padding: 0px;
+ border: 4px solid black;
+ }
+</style>
+<body>
+<main>
+ <table>
+ <col class="bg">
+ <col class="bg">
+ <tr>
+ <td rowspan=4></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td rowspan=2 colspan=2></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+</main>
+</body>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed-ref.html
new file mode 100644
index 0000000000..8ab0992e08
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed-ref.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<style>
+ body {
+ --peek: LightGreen;
+ --border: transparent;
+ margin:0;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 5px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 99%, blue 99%);
+ background-size: 200px 50px;
+ background-repeat: no-repeat; /* FF defaults to no-repeat, Chrome to repeat */
+ }
+ main > * {
+ box-sizing: border-box;
+ }
+ .table {
+ width: 200px;
+ position: relative;
+ margin-top: 5px;
+ margin-left:5px;
+ }
+ .row {
+ width: 200px;
+ height: 50px;
+ }
+ .cell {
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+ vertical-align: top;
+ }
+ .bigsquarecell {
+ width: 100px;
+ height: 100px;
+ display: inline-block;
+ vertical-align: top;
+ background-position-x: -50px;
+ }
+ .c2 {
+ background-position-x: -50px
+ }
+ .c3 {
+ background-position-x: -100px;
+ }
+ .c4 {
+ background-position-x: -150px;
+ }
+ .bottomrow > .cell {
+ margin-top: 5px;
+ }
+</style>
+<main>
+<div class="table">
+<div class="row bg"></div>
+<div><div class="cell firstcell bg"></div><div class="bigsquarecell bg"></div><div class="cell c4 bg"></div></div>
+<div class="row bg"></div>
+<div style="position:absolute;top:-5px;left:-5px;bottom:-5px;right:-5px;border: 10px solid var(--border)"></div>
+</div>
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed.html
new file mode 100644
index 0000000000..c70c6abd92
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-collapsed.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<title>Collapsed table row background image geometry</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#drawing-backgrounds-and-borders" />
+<link rel="match" href="background-image-row-collapsed-ref.html" />
+<style>
+ body {
+ --peek: LightGreen;
+ --border: transparent;
+ margin:0;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 5px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 99%, blue 99%);
+ background-repeat: no-repeat;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+ main table {
+ border: 10px solid var(--border);
+ border-collapse: collapse;
+ }
+ main td {
+ width: 50px;
+ height: 50px;
+ padding: 0px;
+ }
+</style>
+<body>
+<main>
+ <table>
+ <tr class="bg">
+ <td colspan=4></td>
+ </tr>
+ <tr class="bg">
+ <td></td>
+ <td rowspan=2 colspan=2></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr class="bg">
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+</main>
+</body>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-ref.html
new file mode 100644
index 0000000000..1150a63e17
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row-ref.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 5px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 99%, blue 99%);
+ background-size: 230px 50px;
+ background-repeat: no-repeat; /* FF defaults to no-repeat, Chrome to repeat */
+ }
+ main > * {
+ box-sizing: border-box;
+ }
+ .table {
+ border: 10px solid yellow;
+ padding: 10px;
+ width: 290px;
+ }
+ .row {
+ margin-left: 10px;
+ margin-top: 10px;
+ width: 230px;
+ height: 50px;
+ }
+ .cell {
+ margin: 10px;
+ margin-right: 5px;
+ margin-left: 5px;
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+ vertical-align: top;
+ }
+ .firstcell {
+ margin-left: 10px;
+ }
+ .bigsquarecell {
+ margin:10px;
+ margin-left: 5px;
+ margin-right: 5px;
+ margin-bottom: 5px;
+ width: 110px;
+ height: 110px;
+ display: inline-block;
+ vertical-align: top;
+ background-position-x: -60px;
+ }
+ .c2 {
+ background-position-x: -60px
+ }
+ .c3 {
+ background-position-x: -120px;
+ }
+ .c4 {
+ background-position-x: -180px;
+ }
+ .bottomrow > .cell {
+ margin-top: 5px;
+ }
+</style>
+<main>
+<div class="table">
+<div class="row bg"></div>
+<div><div class="cell firstcell bg"></div><div class="bigsquarecell bg"></div><div class="cell c4 bg"></div></div>
+<div class="bottomrow"><div class="cell firstcell bg"></div><div class="cell c2 bg"></div><div class="cell c3 bg"></div><div class="cell c4 bg"></div>
+</div>
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row.html b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row.html
new file mode 100644
index 0000000000..69105e6937
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/background-image-row.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Table row background image geometry</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#drawing-backgrounds-and-borders" />
+<link rel="match" href="background-image-row-ref.html" />
+<meta name="assert" content="Row backgrounds get painted into cells with correct geometry.">
+<style>
+ body {
+ --peek: LightGreen;
+ }
+ .bg {
+ background-color: var(--peek);
+ background-image: linear-gradient(45deg, orange 0px, orange 5px, gainsboro 3px, gainsboro 25%, rgba(160,160,160,0.5) 25%, rgba(160,160,160,0.5) 50%, silver 50%, silver 75%, darkgray 75%, darkgray 99%, blue 99%);
+ background-size: 230px 50px;
+ background-repeat: no-repeat;
+ /* FF sometimes defaults to no-repeat for background images */
+ }
+ main > * {
+ box-sizing: border-box;
+ }
+ main table {
+ border-spacing: 10px;
+ border: 10px solid yellow;
+ padding: 10px;
+ }
+ main td {
+ width: 50px;
+ height: 50px;
+ padding: 0px;
+ }
+</style>
+<body>
+<main>
+ <table>
+ <tr class="bg">
+ <td colspan=4></td>
+ </tr>
+ <tr class="bg">
+ <td></td>
+ <td rowspan=2 colspan=2></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr class="bg">
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+</main>
+</body>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell-ref.html
new file mode 100644
index 0000000000..40d80cac48
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<style>
+body {
+ --bluetrans: rgba(0,0,255,0.5);
+ --yellowtrans: rgba(255,255, 0, 0.5);
+ --orangetrans: rgba(255,165,0,0.5);
+ --greentrans: rgba(0,255,0, 0.5);
+}
+body * {
+ box-sizing: border-box;
+}
+#container > * {
+ position:absolute;
+}
+</style>
+<div id="container" style="position:relative;width:200px;height:200px">
+ <!-- blues -->
+ <div style="width:56px;height:150px;background:var(--bluetrans);border: 6px solid blue;border-bottom:none;"></div>
+ <div style="width:56px;height:56px;top:150px;background:var(--bluetrans);border-left: 6px solid blue;border-bottom:6px solid blue;"></div>
+ <!-- green -->
+ <div style="width:94px;height:55px;top:51px;left:56px;background:var(--greentrans);border-top:4px solid green;"></div>
+ <div style="width:99px;height:44px;top:106px;left:56px;
+ background:var(--greentrans);border-right:4px solid green;"></div>
+ <!-- yellow -->
+ <div style="width:56px;height:56px;top:50px;left:150px;background:var(--yellowtrans);border:6px solid yellow"></div>
+ <!-- orange -->
+ <div style="width:156px;height:56px;top:150px;left:50px;background:var(--orangetrans);border: 6px solid orange"></div>
+ <!-- transparent -->
+ <div style="width:48px;height:49px;top:2px;left:56px;border-top: 2px solid black;border-right:2px solid black"></div>
+ <div style="width:50px;height:48px;top:2px;left:104px;border-top: 2px solid black;border-right:2px solid black"></div>
+ <div style="width:50px;height:48px;top:2px;left:154px;border-top: 2px solid black;border-right:2px solid black"></div>
+ <div style="width:50px;height:44px;top:106px;left:154px;border-right:2px solid black"></div>
+</div>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell.html b/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell.html
new file mode 100644
index 0000000000..60e1390b7b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/collapsed-border-large-cell.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<title>Collapsed borders of large cells</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#drawing-backgrounds-and-borders" />
+<link rel="match" href="collapsed-border-large-cell-ref.html" />
+<meta name="assert" content="Collapsed borders of large cells can collapse a single edge.">
+<style>
+main * {
+ box-sizing: border-box;
+}
+main table {
+ border-collapse: collapse;
+}
+main td {
+ padding:0px;
+ width: 50px;
+ height:50px;
+ border: 2px solid black;
+}
+</style>
+<main>
+ <table>
+ <colgroup style="border:6px solid blue;background:rgba(0,0,255,0.5);"></colgroup>
+ <tr>
+ <td rowspan=4></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td rowspan=2 colspan=2 style="border:4px solid green; background: rgba(0,255,0, 0.5);"></td>
+ <td style="border: 6px solid yellow;background:rgba(255,255, 0, 0.5)"></td>
+ </tr>
+ <td></td>
+ <tr>
+ <td colspan=3 style="border:6px solid orange;background:rgba(255,165,0,0.5)"></td>
+ </tr>
+ </table>
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table-ref.html b/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table-ref.html
new file mode 100644
index 0000000000..fca7b4196c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<style>
+main * {
+ box-sizing: border-box;
+}
+main .table {
+ overflow: hidden;
+ border: 20px solid green;
+ width:90px;
+}
+main .caption {
+ height: 30px;
+ background: lightblue;
+ width:90px;
+ text-align: center;
+}
+main .cell {
+ padding:0px;
+ width: 50px;
+ height:50px;
+}
+</style>
+<main>
+ <div class="table">
+ <div class="cell">
+ <div style="width:50px;height:50px">
+ <div style="width:500px;height:500px;background:pink"></div>
+ </div>
+ </div>
+ </div>
+<div class="caption" style="caption-side:bottom">caption</caption>
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table.html b/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table.html
new file mode 100644
index 0000000000..dc252b1652
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/paint/overflow-hidden-table.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Overflow hidden and captions</title>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#global-style-overrides" />
+<link rel="match" href="overflow-hidden-table-ref.html" />
+<meta name="assert" content="Overflow hidden clips table grid, but not captions.">
+<style>
+main * {
+ box-sizing: border-box;
+}
+main table {
+ overflow: hidden;
+ border: 20px solid green;
+ border-spacing: 0px;
+}
+main caption {
+ height: 30px;
+ background: lightblue;
+}
+main td {
+ padding:0px;
+ width: 50px;
+ height:50px;
+}
+</style>
+<main>
+ <table>
+ <tr>
+ <td>
+ <div style="width:50px;height:50px">
+ <div style="width:500px;height:500px;background:pink"></div>
+ </div>
+ </td>
+ </tr>
+ <caption style="caption-side:bottom">caption</caption>
+ </table>
+</main>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/position-sticky-container.html b/testing/web-platform/tests/css/css-tables/tentative/position-sticky-container.html
new file mode 100644
index 0000000000..604b536df1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/position-sticky-container.html
@@ -0,0 +1,170 @@
+<!doctype html>
+<title>Table parts sticky containers</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<link rel="author" title="Aleks Totic" href="mailto:atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/" />
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5020"/>
+<style>
+ body {
+ margin: 0;
+ }
+ main * {
+ box-sizing: border-box;
+ }
+
+ main .scroller {
+ width: 350px;
+ height: 302px;
+ overflow-y: scroll;
+ outline-offset: -1px;
+ outline: gray solid 1px;
+ }
+ main .padblock {
+ width: 300px;
+ height: 400px;
+ outline-offset: -2px;
+ outline: black dotted 2px;
+ }
+ main table {
+ border-spacing: 0;
+ }
+
+ main td {
+ width: 100px;
+ height: 25px;
+ }
+ .sticky {
+ position:sticky;
+ top: 0;
+ background: rgba(0,255,0, 0.3);
+ }
+
+</style>
+<main>
+ <div class="scroller">
+ <div class="padblock">top</div>
+ <table>
+ <thead>
+ <tr>
+ <td>h:0,0</td>
+ <td>h:0,1</td>
+ <td>h:0,2</td>
+ </tr>
+ <tr >
+ <td>h:1,0</td>
+ <td >h:1,1</td>
+ <td>h:1,2</td>
+ </tr>
+ <tr>
+ <td>h:2,0</td>
+ <td>h:2,1</td>
+ <td>h:2,2</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>b:0,0</td>
+ <td>b:0,1</td>
+ <td>b:0,2</td>
+ </tr>
+ <tr>
+ <td>b:1,0</td>
+ <td>b:1,1</td>
+ <td>b:1,2</td>
+ </tr>
+ <tr>
+ <td>b:2,0</td>
+ <td>b:2,1</td>
+ <td>b:2,2</td>
+ </tr>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td>f:0,0</td>
+ <td>f:0,1</td>
+ <td>f:0,2</td>
+ </tr>
+ <tr>
+ <td>f:1,0</td>
+ <td>f:1,1</td>
+ <td>f:1,2</td>
+ </tr>
+ <tr>
+ <td>f:2,0</td>
+ <td>f:2,1</td>
+ <td>f:2,2</td>
+ </tr>
+ </tfoot>
+ </table>
+ <div class="padblock">bottom</div>
+ </div>
+</main>
+<script>
+
+ function scrollTo(y) {
+ let scroller = document.querySelector("main .scroller");
+ scroller.scrollTop = y;
+ }
+
+ test( () => {
+ // Setup
+ let target = document.querySelector("main tbody tr:nth-child(2) td:nth-child(2)");
+ let scroller = document.querySelector("main .scroller");
+ target.classList.toggle("sticky");
+
+ // Tests
+ scrollTo(0);
+ assert_equals(target.getBoundingClientRect().top, 500, "intrinsic position");
+
+ scrollTo(600);
+ assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table");
+
+ scrollTo(640);
+ assert_equals(target.getBoundingClientRect().top, -40, "sticking to the table bottom");
+
+ // Teardown
+ target.classList.toggle("sticky");
+ }, "TD sticky container is table");
+
+ test( () => {
+ // Setup
+ let target = document.querySelector("main tbody tr:nth-child(2)");
+ let scroller = document.querySelector("main .scroller");
+ target.classList.toggle("sticky");
+
+ // Tests
+ scrollTo(0);
+ assert_equals(target.getBoundingClientRect().top, 500, "intrinsic position");
+
+ scrollTo(600);
+ assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table");
+
+ scrollTo(640);
+ assert_equals(target.getBoundingClientRect().top, -40, "sticking to the table bottom");
+ // Teardown
+ target.classList.toggle("sticky");
+ }, "TR sticky container is table");
+
+
+ test( () => {
+ // Setup
+ let target = document.querySelector("main tbody");
+ let scroller = document.querySelector("main .scroller");
+ target.classList.toggle("sticky");
+
+ // Tests
+ scrollTo(0);
+ assert_equals(target.getBoundingClientRect().top, 475, "intrinsic position");
+
+ scrollTo(550);
+ assert_equals(target.getBoundingClientRect().top, 0, "sticking to the table");
+
+ scrollTo(600);
+ assert_equals(target.getBoundingClientRect().top, -50, "sticking to the table bottom");
+
+ // Teardown
+ target.classList.toggle("sticky");
+ }, "TBODY sticky container is table");
+
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/rowspan-height-redistribution.html b/testing/web-platform/tests/css/css-tables/tentative/rowspan-height-redistribution.html
new file mode 100644
index 0000000000..364ae321c9
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/rowspan-height-redistribution.html
@@ -0,0 +1,503 @@
+<!doctype html>
+<title>ROWSPAN redistribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout" />
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4418" />
+<style>
+ main table {
+ margin-top: 8px;
+ border-collapse: collapse;
+ background: rgba(0,0,255,0.1);
+ 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%);
+ background-size: 20px 20px;
+ background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
+ }
+ .sizer {
+ width: 30px;
+ height: 100px;
+ }
+ main tbody tr:nth-child(odd) {
+ background: rgba(255,255,0,1.0);
+ }
+ main tbody tr:nth-child(even) {
+ background: rgba(255,165,0,1.0);
+ }
+ main td div {
+ background: radial-gradient(ellipse at center, rgba(255,255,255,0.5) 0%, rgba(0,255,0,0.7) 100%);
+ }
+ main .td-padding td {
+ padding: 2px;
+ }
+ main .td-padding-xl td {
+ padding: 10px;
+ }
+</style>
+<main>
+<h1>ROWSPAN > 1 to row distribution</h1>
+<p>The algorithm has not been standardized. This is my understanding of how it works.</p>
+<ol>
+ <li>rowspan>1 TDs are sorted:</li>
+ <ol>
+ <li>If TD span the same rows, taller TD is distributed first.</li>
+ <li>If one TD is fully enclosed by another, inner TD is distributed first.</li>
+ <li>Otherwise, higher TD is distributed first.</li>
+ </ol>
+ <li>Each rowspan>1 TD's height is distributed as following</li>
+ <ol>
+ <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>
+ <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>
+ <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>
+ <li>Unconstrained non-empty rows grow, proportional to their existing height.</li>
+ <li>If all rows are empty, last row gets all the height. Justification: ???</li>
+ <li>Contstrained rows grow in proportion to current height.</li>
+ </ol>
+ </ol>
+<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>
+ <p class="error">Safari fails most of these tests</p>
+<p>Color scheme</p>
+<table>
+ <tr>
+ <td>odd rows are yellow</td>
+ </tr>
+ <tr>
+ <td>even rows are orange</td>
+ </tr>
+ <tr>
+ <td><div style="height:50px">inner divs have a green gradient</div>
+ </td>
+ </tr>
+ <tr>
+ <td>row</td>
+ </tr>
+ <tr>
+ <td>row</td>
+ </tr>
+ <tr>
+ <td>row</td>
+ </tr>
+ <tr>
+ <td>row</td>
+ </tr>
+
+</table>
+<h2>Unconstrained rows</h2>
+ <p>Rows whose height is not fixed or percent are unconstrained.</p>
+<p class="testdesc">Unconstrained rows
+Unconstrained rows are redistributed proportionally. Rows are constrained if their height is fixed, or percent.</p>
+<table>
+ <tbody>
+ <tr data-expected-height="50">
+ <td>0,0</td>
+ <td rowspan="2"><div class="sizer"></div></td>
+ </tr>
+ <tr data-expected-height="50">
+ <td>0,1</td>
+ </tr>
+</table>
+
+<p class="testdesc">Unconstrained rows with zero height do not grow.</p>
+<table>
+ <tbody>
+ <tr data-expected-height="50">
+ <td>0,0</td>
+ <td rowspan="3"><div class="sizer"></div></td>
+ </tr>
+ <tr data-expected-height="0">
+ </tr>
+ <tr data-expected-height="50">
+ <td>0,2</td>
+ </tr>
+</table>
+
+<p class="testdesc">rowspan>1 is zero height, spanned rows have height.</p>
+<table>
+ <tbody>
+ <tr data-expected-height="0">
+ <td></td>
+ <td rowspan="3"><div class="sizer"></div></td>
+ <td></td>
+ </tr>
+ <tr data-expected-height="50">
+ <td>1,0</td>
+ <td></td>
+ </tr>
+ <tr data-expected-height="50">
+ <td>2,0</td>
+ <td></td>
+ </tr>
+</table>
+
+<p class="testdesc">Unconstrained rows are redistributed proportionally to heights</p>
+<table>
+ <tbody>
+ <tr data-expected-height="75">
+ <td><div style="height:45px">0,0</div></td>
+ <td rowspan="2"><div class="sizer"></div></td>
+ </tr>
+ <tr data-expected-height="25">
+ <td><div style="height:15px">0,1</div></td>
+ </tr>
+</table>
+
+<h2>Fixed rows</h2>
+
+<p class="testdesc">Constrained fixed rows
+do not grow if there are unconstrained ones</p>
+<p class="error">Edge grows constrained rows too</p>
+<table>
+ <tbody>
+ <tr style="height: 30px" data-expected-height="30">
+ <td>0,0 30px</td>
+ <td rowspan="2"><div class="sizer"></div></td>
+ </tr>
+ <tr data-expected-height="70">
+ <td>0,1</td>
+ </tr>
+</table>
+
+<p class="testdesc"> Constrained fixed rows
+grow proportionally to their size if there are no unconstrained rows</p>
+<table>
+ <tbody>
+ <tr style="height: 20px" data-expected-height="25">
+ <td>20</div></td>
+ <td rowspan="3"><div class="sizer"></div></td>
+ </tr>
+ <tr style="height: 20px" data-expected-height="25">
+ <td>20</td>
+ </tr>
+ <tr style="height: 40px" data-expected-height="50">
+ <td>40</td>
+ </tr>
+</table>
+
+<h2>Percent rows</h2>
+
+<p class="testdesc">Constrained percent rows
+grow like unconstrained ones when percent resolution size is undefined.</p>
+<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>
+<table>
+ <tbody>
+ <tr style="height: 30%" data-expected-height="50">
+ <td>0,0 30%</td>
+ <td rowspan="2"><div class="sizer"></div></td>
+ </tr>
+ <tr data-expected-height="50">
+ <td>0,1</td>
+ </tr>
+ <tr style="height:100px"><td>100px</td></tr>
+</table>
+
+
+<p class="testdesc">Percent rows with zero height
+do not grow.</p>
+<p class="error">Legacy Chrome has a strange gap between rows</p>
+<table>
+ <tbody>
+ <tr data-expected-height="50">
+ <td>0,0</td>
+ <td rowspan="3"><div class="sizer"></div></td>
+ </tr>
+ <tr style="height:10%;background:red" data-expected-height="0">
+ </tr>
+ <tr data-expected-height="50">
+ <td>2,0</td>
+ </tr>
+</table>
+
+<h2>Order of rowspan distribution</h2>
+
+
+<p class="testdesc">If cells span the same rows, bigger cell is distributed first
+Not sure how to test this, I think it is just an optimization, there is no observable effect.
+<p class="error">FF and Legacy Chrome unexpectedly distribute height evenly between rows in the first test case. Edge and TablesNG do not.</p>
+<table>
+ <tr data-expected-height=0>
+ <td rowspan=3><div style="height:50px"></div></td>
+ <td rowspan=3><div style="height:99px"></div></td>
+ </tr>
+ <tr data-expected-height=0>
+ </tr>
+ <tr data-expected-height=99>
+ </tr>
+ <tr>
+ <td>bottom</td>
+ <td>bottom</td>
+ </tr>
+</table>
+<table>
+ <tr data-expected-height=0>
+ <td rowspan=3><div style="height:50px"></div></td>
+ <td rowspan=3><div style="height:99px"></div></td>
+ <td style="width:20px"></td>
+ </tr>
+ <tr data-expected-height=0>
+ <td></td>
+ </tr>
+ <tr data-expected-height=99>
+ <td></td>
+ </tr>
+ <tr>
+ <td>bottom</td>
+ <td>bottom</td>
+ </tr>
+</table>
+<table>
+ <tr data-expected-height=0>
+ <td rowspan=3><div style="height:99px;width:20px"></div></td>
+ </tr>
+ <tr></tr>
+ <tr data-expected-height=99></tr>
+ <tr>
+ <td>bottom</td>
+ <td>bottom</td>
+ </tr>
+</table>
+
+
+<p class="testdesc">If one cell is fully enclosed by another, inner cell wins.
+<p class="error">Not in Edge</p>
+<table>
+ <tr data-expected-height=0>
+ <td rowspan=4><div style="height:50px;width:20px"></div></td>
+ <td></td>
+ <tr data-expected-height=0>
+ <td></td>
+ <td rowspan=2><div style="height:100px;width:20px"></div></td>
+ </tr>
+ <tr data-expected-height=100></tr>
+ <tr data-expected-height=0></tr>
+</tr>
+</table>
+
+<p class="testdesc">First row wins.
+rowspan-4 distributes 50 to last empty row, row3. rowspan-3 distributes 100px to only nonempty row, row3.
+<p class="error">Edge disagrees here.</p>
+<table>
+ <tr data-expected-height=0>
+ <td rowspan=4><div style="height:50px;width:20px"></div></td>
+ <td></td>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=100>
+ <td></td>
+ <td rowspan=3><div style="height:100px;width:20px"></div></td>
+ </tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+</tr>
+</table>
+
+<h2>Rowspan distribution over empty rows.</h2>
+
+<p class="testdesc">Rowspans that span non-existent rows
+Span is truncated so only existing rows are spanned.</p>
+<table>
+ <tbody data-expected-height="100">
+ <tr>
+ <td data-expected-height="50">0,0</td>
+ <td data-expected-height="100" rowspan="5"><div style="height:100px;">rowspan 5</div></td>
+ </tr>
+ <tr>
+ <td data-expected-height="50">1,0</td>
+ </tr>
+ <tr data-expected-height="0"></tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td>body 2</td>
+ </tr>
+ </tbody>
+</table>
+
+<p class="testdesc">Rowspan spans only empty rows
+Last spanned row gets all the height.
+<p class="error">Edge distributes height to all empty rows, not just last.</p>
+<table>
+ <tr>
+ <td>first row</td>
+ </tr>
+ <tr data-expected-height=0>
+ <td></td>
+ <td rowspan=5><div style="height:100px;width:30px;"></div></td>
+ </tr>
+ <tr data-expected-height=0><td></td></tr>
+ <tr data-expected-height=0><td></td></tr>
+ <tr data-expected-height=0><td></td></tr>
+ <tr data-expected-height=100><td></td></tr>
+ <tr>
+ <td>last row</td>
+ </tr>
+</table>
+
+<p class="testdesc">TD is not considered empty if it has padding, but no content
+<table>
+ <tr>
+ <td>first row</td>
+ </tr>
+ <tr data-expected-height=0>
+ <td></td>
+ <td style="height:100px" rowspan=3></td>
+ </tr>
+ <tr data-expected-height=100><td style="padding:2px"></td></tr>
+ <tr data-expected-height=0></tr>
+ <tr>
+ <td>last row</td>
+ </tr>
+</table>
+
+<p class="testdesc">row with an empty tall cell is not considered empty.
+<p class="error">
+<table>
+ <tr>
+ <td rowspan=5><div style="height:100px">rowspan</div></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr data-expected-height=100>
+ <td rowspan=5></td>
+ <td></td>
+ </tr>
+ <tr></tr>
+ <tr></tr>
+ <tr></tr>
+ <tr></tr>
+</table>
+
+<p class="testdesc">Empty rows with border-spacing big enough for rowspan cell
+rows are 0 height, cell spans the entire table.
+<table style="border-spacing:20px;border-collapse:separate " data-expected-height=100>
+ <tr data-expected-height=0>
+ <td rowspan=4><div style="height:60px;width:40px"></div></td>
+ </tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+</table>
+
+<p class="testdesc">row with a non-empty rowspan>0 cell is empty.
+Distributes to all rows except start row?
+<p class="error">
+<table>
+ <tr>
+ <td rowspan=5><div style="height:100px">rowspan</div></td>
+ <td></td>
+ </tr>
+ <tr data-expected-height=100>
+ <td rowspan=5><div style="height:100px">rowspan</div></td>
+ </tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+ <tr></tr>
+ <tr></tr>
+</table>
+<table>
+ <tr>
+ <td rowspan=5><div style="height:100px">rowspan</div></td>
+ <td></td>
+ </tr>
+ <tr data-expected-height=100>
+ <td>yo</td>
+ </tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+ <tr data-expected-height=0></tr>
+</table>
+
+
+<p class="testdesc">Distribution over rowspan > 1 rows
+Distribution over rowspan > 1 rows
+
+<table class="td-padding-xl" data-expected-height=360>
+ <tr>
+ <td rowspan=6><div style="width:50px;height:280px"></div></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr style="height:30%;background:purple">
+ <td data-expected-height=20></td>
+ </tr>
+ <tr data-expected-height=110>
+ <td rowspan=7 ></td>
+ </tr>
+ <tr data-expected-height=110>
+ <td rowspan=17 ><div style="width:50px;height:40px"></div></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+</table>
+
+<p class="testdesc">Distribution of table height over rowspan > 1 rows
+If there are any unconstrained non-empty rows, they get it.
+When all rows are empty, last row takes it</p>
+<table class="td-padding-xl" style="height:460px">
+ <tr>
+ <td rowspan=6><div style="width:50px;height:280px" data-expected-height=280></div></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr style="height:30%;background:purple" data-expected-height=120>
+ <td ></td>
+ </tr>
+ <tr data-expected-height=110>
+ <td rowspan=7 ></td>
+ </tr>
+ <tr data-expected-height=110>
+ <td rowspan=17><div style="width:50px;height:40px"></div></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+ <tr>
+ <td></td>
+ </tr>
+</table>
+
+<p class="testdesc">Distribution of rowspan over percentage rows
+Percentage rows are considered empty if they cannot resolve</p>
+<table>
+ <tbody>
+ <tr style="height:20%">
+ <td rowspan=3><div style="height:100px;width:100px"></div></td>
+ <td></td>
+ </tr>
+ <tr style="height:30%">
+ <td></td>
+ </tr>
+ <tr data-expected-height=100 style="height:50%">
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-fixed-distribution.html b/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-fixed-distribution.html
new file mode 100644
index 0000000000..dd403d248c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-fixed-distribution.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4418">
+<p>Test passes if there is a filled green square.</p>
+<div style="display: table; width: 100px; height: 100px;">
+ <div style="display: table-header-group; background: green; height: 20px;">
+ <div></div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-percent-distribution.html b/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-percent-distribution.html
new file mode 100644
index 0000000000..d1546b1e38
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/section-no-tbody-percent-distribution.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/4418">
+<p>Test passes if there is a filled green square.</p>
+<div style="display: table; width: 100px; height: 100px;">
+ <div style="display: table-header-group; background: green; height: 20%;">
+ <div></div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/support/README b/testing/web-platform/tests/css/css-tables/tentative/support/README
new file mode 100644
index 0000000000..67e87ca891
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/support/README
@@ -0,0 +1,13 @@
+This test suite is created as part of Chrome's NG table rewrite in 2020.
+TablesNG: https://crbug.com/958381
+
+Many parts of table layout algorithm have been left unspecified by the
+existing specification:
+https://www.w3.org/TR/css-tables-3/
+
+These tests are an attempt to exaustively test all parts of the
+algorithm. When specification did not specify the algorithm,
+the proposed algorithm is described in the tests.
+
+Our goal is that these tests will guide creation of a more complete
+table standard.
diff --git a/testing/web-platform/tests/css/css-tables/tentative/support/table-tentative.css b/testing/web-platform/tests/css/css-tables/tentative/support/table-tentative.css
new file mode 100644
index 0000000000..08d65b2b87
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/support/table-tentative.css
@@ -0,0 +1,34 @@
+/*
+Tables-ng test styling.
+
+Usage:
+
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<p class="testdesc">Short description here
+ Analysis
+<p class="error">Current disagreements between browsers</p>
+*/
+main td {
+ padding: 0;
+}
+.error {
+ color: #b70000;
+}
+p {
+ margin-top:4px;
+ margin-bottom:4px;
+}
+body {
+ counter-reset: testid;
+}
+.testdesc {
+ white-space: pre-line;
+ margin-top: 16px;
+}
+.testdesc:before {
+ content: counter(testid) ". ";
+ counter-increment: testid;
+}
+.testdesc:first-line {
+ font-family: monospace;
+}
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-fixed-minmax.html b/testing/web-platform/tests/css/css-tables/tentative/table-fixed-minmax.html
new file mode 100644
index 0000000000..5be81d2056
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-fixed-minmax.html
@@ -0,0 +1,146 @@
+<!doctype html>
+<title>Table minmax tricks</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/" />
+<style>
+ main table {
+ table-layout:fixed;
+ width: 100%;
+ background: #ddd;
+ border-spacing: 0;
+ }
+ main td {
+ padding: 0;
+ }
+</style>
+<h1>Infinite intrinsic table widths</h1>
+<p>Originally, algorithm for computing intrinsic table inline size had a special case: <br>
+ If table is fixed, and has a width:%, its intrinsic inline size was "infinite". <br>
+This ensured that fixed table with 100% width inside block layout would expand to container's width. </p>
+<p>Different containers do not have reasonable handling of intrinsic infinitely sized
+children. For those, table's intrinsic size should never be infinite, but instead
+default to regular max size.</p>
+
+<main>
+<h3>Flexbox</h3>
+
+<p>flex width:auto</p>
+<div id="flextest" style="display:flex;">
+ <table>
+ <td>flex</td>
+ </table>
+ <div style="width:98px;border:1px solid black;flex-shrink:0">flex div</div>
+</div>
+
+<p>flex width:max-content</p>
+<div id="flextest_max" style="display:flex;width:max-content">
+ <table>
+ <td><div style="width:100px">flex</div></td>
+ </table>
+ <div style="width:100px;border:1px solid black;flex-shrink:0">flex div</div>
+</div>
+
+<p>flex width:min-content</p>
+<div id="flextest_min1" style="display: flex; width: min-content;">
+ <table style="flex: 0 0 content; min-width: 0px;">
+ <td style="width: 100px;"></td>
+ </table>
+</div>
+
+<div id="flextest_min2" style="display: flex; width: min-content;">
+ <div style="flex: 0 0 auto; min-width: 0px;">
+ <table>
+ <td style="width: 100px;"></td>
+ </table>
+ </div>
+</div>
+
+<h3>Grid</h3>
+<p>grid width:auto</p>
+<div id="grid" style="display:grid;grid-template-columns: 1fr;width:auto">
+ <table>
+ <td><div style="width:100px">grid</div></td>
+ </table>
+</div>
+<p>grid width:max-content</p>
+<div id="grid_max" style="display:grid;grid-template-columns: 1fr;width:max-content">
+ <table>
+ <td><div style="width:100px">grid</div></td>
+ </table>
+</div>
+
+<h3>Table</h3>
+<table id="table_container" style="table-layout:auto;width:auto; background: #aaa;">
+ <tr>
+ <td>
+ <table>
+ <td><div style="width:100px">table</div></td>
+ </table>
+ </td>
+ </tr>
+</table>
+
+<h3>Absolute</h3>
+<div id="absolute" style="width:400px;height:100px;outline:solid 1px green;position:relative">
+ <table style="position:absolute;right:0;top:0">
+ <td>absolute</td>
+ </table>
+</div>
+
+<script>
+ test(_ => {
+ let flexbox = document.querySelector("#flextest");
+ let table = flexbox.querySelector("table");
+ let div = flexbox.querySelector("div");
+ assert_equals(div.offsetWidth, 100);
+ assert_equals(flexbox.offsetWidth, document.body.offsetWidth);
+ assert_equals(flexbox.offsetWidth, table.offsetWidth + div.offsetWidth);
+ }, "table's width inside flexbox width:auto is not infinite");
+
+ test(_ => {
+ let flexbox = document.querySelector("#flextest_max");
+ let table = flexbox.querySelector("table");
+ assert_greater_than(table.offsetWidth, document.body.offsetWidth);
+ }, "table's width inside flexbox width:max-content is infinite");
+
+ test(_ => {
+ let flexbox = document.querySelector("#flextest_min1");
+ let table = flexbox.querySelector("table");
+ assert_equals(flexbox.offsetWidth, 100);
+ assert_greater_than(table.offsetWidth, document.body.offsetWidth);
+ }, "table's width inside flexbox width:min-content is infinite, but the flexbox is finite; scenario 1");
+
+ test(_ => {
+ let flexbox = document.querySelector("#flextest_min2");
+ let table = flexbox.querySelector("table");
+ assert_equals(flexbox.offsetWidth, 100);
+ assert_greater_than(table.offsetWidth, document.body.offsetWidth);
+ }, "table's width inside flexbox width:min-content is infinite, but the flexbox is finite; scenario 2");
+
+ test(_ => {
+ let grid = document.querySelector("#grid");
+ let table = grid.querySelector("table");
+ assert_equals(grid.offsetWidth, document.body.offsetWidth);
+ assert_equals(grid.offsetWidth, table.offsetWidth);
+ }, "table's width inside grid width:auto is not infinite");
+
+ test(_ => {
+ let grid = document.querySelector("#grid_max");
+ let table = grid.querySelector("table");
+ assert_greater_than(table.offsetWidth, document.body.offsetWidth);
+ }, "table's width inside grid width:max-content is infinite");
+
+ test(_ => {
+ let table = document.querySelector("#table_container");
+ assert_equals(table.offsetWidth, document.body.offsetWidth);
+ }, "table's width inside a table cell is infinite");
+
+ test(_ => {
+ let abs = document.querySelector("#absolute");
+ let table = abs.querySelector("table");
+ assert_equals(table.offsetWidth, abs.offsetWidth);
+ }, "table's width inside an absolute block is infinite");
+
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-height-redistribution.html b/testing/web-platform/tests/css/css-tables/tentative/table-height-redistribution.html
new file mode 100644
index 0000000000..c0f48e4f20
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-height-redistribution.html
@@ -0,0 +1,317 @@
+<!doctype html>
+<title>TABLE height redistribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel='stylesheet' href='../support/base.css' />
+<link rel='stylesheet' href='./support/table-tentative.css' />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout" />
+<style>
+ main table {
+ border-spacing: 0px;
+ background: rgba(255,0,0,0.3);
+ height: 100px;
+ width: 100px;
+ }
+ main td {
+ padding: 0;
+ }
+ main table tbody:nth-child(1) {
+ background: #CCC;
+ }
+ main table tbody:nth-child(2) {
+ background: #AAA;
+ }
+ main table tbody:nth-child(3) {
+ background: #999;
+ }
+ main table thead {
+ background: rgba(0,255,0,0.3);
+ }
+ main table tfoot {
+ background: rgba(255,255,0,0.3);
+ }
+
+ .debug {
+ width:100px;
+ height:1px;
+ position:relative;
+ }
+ .debug pre {
+ position:absolute;
+ font: 30px/30px monospace;
+ left: 120px;
+ top:-30px;
+ }
+
+</style>
+<main>
+ <h1>Tests for redistribution of table height to row group height.</h1>
+ <p>This algorithm has not been standardized. Browsers implementations disagree a lot.
+ Legacy Chrome used to always distribute all the height to the first tbody.</p>
+
+<pre class=error>Major incompatibility: Legacy:
+- ignores any height set on sections.
+- does not size the table unless section has a TR
+- does not grow sections without TDs
+- only distributes height to the 1st tbody
+FF
+- does not prioritize thead for height distribution most of the time.
+- y offset of multiple tbodies can be incorrect.
+</pre>
+
+<h2>Empty table</h2>
+<p>Empty tables always grow to specified height in all browsers.</p>
+<p class="testdesc">no sections</p>
+<table data-expected-height=100></table>
+
+<p class="testdesc">no sections, no border spacing</p>
+<table style="border-spacing: 0" data-expected-height=100></table>
+
+<p class="testdesc">collapsed table no sections</p>
+<table style="border-collapse:collapse" data-expected-height=100></table>
+
+<p class="testdesc">fixed table no sections</p>
+<table style="table-layout:fixed" data-expected-height=100></table>
+
+<h2>One TBODY</h2>
+<p>The big difference here is between empty TBODY, and a body with an empty TR</p>
+<li>FF: always sizes the table, only sizes TBODY if it has TR.</li>
+<li>Legacy: does not size the table unless TBODY has TR</li>
+<p>FF: sizes the table, but tbody size remains 0 unless tbody is not empty.</p>
+<p>Legacy table size remains 0, or border-spacing</p>
+
+<p class="testdesc">single empty tbody</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=100></tbody>
+</table>
+
+<p class="testdesc">single tbody+tr</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">border spacing</p>
+<p class="error">FF/Legacy do not apply border-spacing</p>
+<table style="border-spacing: 10px" data-expected-height=100>
+ <tbody data-expected-height=80><tr></tr></tbody>
+</table>
+
+<p class="testdesc">collapsed table</p>
+<table style="border-collapse:collapse" data-expected-height=100>
+ <tbody data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">fixed table</p>
+<table style="table-layout:fixed" data-expected-height=100>
+ <tbody data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">tbody has fixed height</p>
+<p class="error">FF adds tbody height to table?</p>
+<table data-expected-height=100>
+ <tbody style="height:50px" data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">tbody has fixed height > table</p>
+<p class="error">Legacy: table size wins. FF: table size wins, but body grows to 300px?</p>
+<table data-expected-height=200>
+ <tbody style="height:200px" data-expected-height=200><tr></tr></tbody>
+</table>
+
+<p class="testdesc">tr has fixed height > table</p>
+<p class="error">FF: table size wins, but body is 300.</p>
+<table data-expected-height=200>
+ <tbody data-expected-height=200><tr style="height:200px"></tr></tbody>
+</table>
+
+<p class="testdesc">tbody has percentage height > table</p>
+<table data-expected-height=100>
+ <tbody style="height:200%" data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">tr has percentage height > table</p>
+<p class=error>FF/Legacy: table wins. FF: body is 200px</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=100><tr style="height:200%"></tr></tbody>
+</table>
+
+<p class="testdesc">non-empty tbody</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">non-empty thead</p>
+<table data-expected-height=100>
+ <thead data-expected-height=100><tr></tr></thead>
+</table>
+
+<h2>THEAD TBODY</h2>
+
+<p class="testdesc">empty thead, empty tbody</p>
+<p class="error">FF thead/tbody both grow</p>
+<table data-expected-height=100>
+ <thead data-expected-height=0><tr></tr></thead>
+ <tbody data-expected-height=100><tr></tr></tbody>
+</table>
+
+<p class="testdesc">sized thead, empty tbody</p>
+<table data-expected-height=100>
+ <thead data-expected-height=20><td style="height:20px">thead</td></thead>
+ <tbody data-expected-height=80><tr></tr></tbody>
+</table>
+
+<p class="testdesc">table layout fixed, thead with td, tbody</p>
+<table style="table-layout:fixed" data-expected-height=100>
+ <thead data-expected-height=20>
+ <tr>
+ <td style="height:20px">thead</td>
+ </tr>
+ </thead>
+ <tbody data-expected-height=80><tr><td>x</td></tr></tbody>
+</table>
+
+<p class="testdesc">table layout fixed, thead+td, tbody+td</p>
+<table style="table-layout:fixed" data-expected-height=100>
+ <thead data-expected-height=20>
+ <tr>
+ <td style="height:20px">thead</td>
+ </tr>
+ </thead>
+ <tbody data-expected-height=80><tr><td>x</td></tr></tbody>
+</table>
+
+<p class="testdesc">thead with td</p>
+<table data-expected-height=100>
+ <thead data-expected-height=20>
+ <tr>
+ <td style="height:20px">thead</td>
+ </tr>
+ </thead>
+ <tbody data-expected-height=80>
+ <tr>
+ </tr>
+ </tbody>
+</table>
+
+<p class="testdesc">tfoot with td</p>
+<table data-expected-height=100>
+ <tfoot data-expected-height=20>
+ <tr>
+ <td style="height:20px">tfoot</td>
+ </tr>
+ </tfoot>
+ <tbody data-expected-height=80>
+ <tr>
+ </tr>
+ </tbody>
+</table>
+
+<h2>Multiple TBODY</h2>
+<p class="error">Legacy does not distribute any heights when tr is empty.</p>
+<p class="error">Legacy always distributes everything to 1st tbody.</p>
+
+<p class="testdesc">2 tbody</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=50><tr></tr></tbody>
+ <tbody data-expected-height=50><tr></tr></tbody>
+</table>
+
+<p class="testdesc">2 tbody, with non-empty tds</p>
+<p class="error">Legacy distributes everything to 1st tbody</p>
+<table data-expected-height=100>
+ <tbody data-expected-height=50><tr><td>x</td></tr></tbody>
+ <tbody data-expected-height=50><tr><td>x</td></tr></tbody>
+</table>
+
+
+<p class="testdesc">2 tbody, 40%, auto, no td</p>
+<p class="error">FF: distributes everything to auto when empty. Legacy does not distribute</p>
+<table data-expected-height=100>
+ <tbody style="height:40%" data-expected-height=40><tr></tr></tbody>
+ <tbody data-expected-height=60><tr></tr></tbody>
+</table>
+
+<p class="testdesc">2 tbody, 40%, auto, non-empty td</p>
+<table data-expected-height=100>
+ <tbody style="height:40%" data-expected-height=40><tr><td>x</td></tr></tbody>
+ <tbody data-expected-height=60><tr><td>x</td></tr></tbody>
+</table>
+
+<p class="testdesc">2 tbody, 40px, auto, non-empty td</p>
+<p class="error">FF gets confused with 2nd body placement</p>
+<table data-expected-height=100>
+ <tbody style="height:40px" data-expected-height=40><tr><td>x</td></tr></tbody>
+ <tbody data-expected-height=60 data-offset-y=40><tr><td>x</td></tr></tbody>
+</table>
+
+<p class="testdesc">2 tbody, 40%, 40px, non-empty td</p>
+<p class="error">FF splits evenly</p>
+<table data-expected-height=100>
+ <tbody style="height:40%" data-expected-height=40><tr><td>x</td></tr></tbody>
+ <tbody style="height:40px" data-expected-height=60 data-offset-y=40><tr><td>x</td></tr></tbody>
+</table>
+
+<h2>Sized THEAD/TBODY</h2>
+<p class=error>FF does not prioritize TBODY for distribution</p>
+<p class="testdesc">20px thead, 30px tbody</p>
+<table data-expected-height=100>
+ <thead data-expected-height=20 style="height:20px">
+ <tr><td>x</td></tr>
+ </thead>
+ <tbody data-expected-height=80 style="height:30px">
+ <tr><td>x</td></tr>
+ </tbody>
+</table>
+
+<p class="testdesc">20px thead's tr, 30px tbody's tr</p>
+<table data-expected-height=100>
+ <thead data-expected-height=20 >
+ <tr style="height:20px"><td>x</td></tr>
+ </thead>
+ <tbody data-expected-height=80 >
+ <tr style="height:30px"><td>x</td></tr>
+ </tbody>
+</table>
+
+<p class="testdesc">20px thead's td, 30px tbody's td</p>
+<table data-expected-height=100>
+ <thead data-expected-height=20 >
+ <tr><td style="height:20px">x</td></tr>
+ </thead>
+ <tbody data-expected-height=80 >
+ <tr><td style="height:30px">x</td></tr>
+ </tbody>
+</table>
+
+</main>
+
+<script>
+ checkLayout("table");
+
+ // Display body sizes next to the table.
+ for (let table of Array.from(document.querySelectorAll("table"))) {
+ let d = document.createElement("div");
+ d.classList.add("debug");
+ let log = document.createElement("pre");
+ d.appendChild(log);
+
+ let text = "";
+ let x;
+ x = table.querySelector("thead");
+ if (x)
+ text += `h:${x.offsetHeight}\n`;
+ x = table.querySelectorAll("tbody");
+ if (x.length > 0)
+ for (body of Array.from(x))
+ text += `b:${body.offsetHeight}\n`;
+ x = table.querySelector("tfoot");
+ if (x)
+ text += `f:${x.offsetHeight}\n`;
+ log.innerText = text;
+
+ table.parentNode.insertBefore(d, table);
+ }
+</script>
+
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-minmax.html b/testing/web-platform/tests/css/css-tables/tentative/table-minmax.html
new file mode 100644
index 0000000000..eda9ce37fb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-minmax.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<title>Table minmax tricks</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/" />
+<style>
+ main table {
+ background: gray;
+ border-spacing: 10px 10px;
+ table-layout: auto;
+ }
+ main td {
+ background: #BFB;
+ font-size: 10px;
+ box-sizing: border-box;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ line-height: 2;
+ }
+ .container {
+ border: 5px solid orange;
+ margin-top: 8px;
+ box-sizing: border-box;
+ width: 600px;
+ }
+</style>
+<main>
+<h2>Table minmax</h2>
+
+<p>How do different layout algorithms deal with table with an infinite max width?`</p>
+<xmp>
+ <table>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:100px">100px</div></td>
+ </table>
+</xmp>
+<p>Block layout clamps the max width, but flex/grid/table layouts do not. What happens?</p>
+
+<p class="testdesc">Block layout</p>
+<div class="container">
+ <table data-expected-width=590>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:100px">100px</div></td>
+ </table>
+ <div>sibling</div>
+</div>
+
+<p class="testdesc">Block layout with floats</p>
+<div class="container">
+ What about this?
+ <table style="float:left" data-expected-width=590>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:100px">100px</div></td>
+ </table>
+ <div style="float:left">sibling</div>
+ <div style="clear:both"></div>
+</div>
+
+
+<p class="testdesc">Table layout</p>
+
+<table class="container" style="width:auto">
+ <td>
+ <table data-expected-width=160>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:50px">50px</div><div style="width:50px">50px</div></td>
+ </table>
+ </td>
+ <td><div style="width:100px;">sibling</div></td>
+</table>
+
+<p class="testdesc">Flex layout 1 1 auto</p>
+<p class="error">Edge is wider than flexbox</p>
+<div class="container" style="display:flex;justify-content:center">
+ <table style="flex: 1 1 auto" data-expected-width=355>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:50px">50px</div><div style="width:50px">50px</div></td>
+ </table>
+ <div style="background:yellow;flex:1 1 40px">40px</div>
+</div>
+
+<p class="testdesc">Flex layout 0 0 auto</p>
+
+<div class="container" style="display:flex;justify-content:center">
+ <table style="flex: 0 0 auto" data-expected-width=160>
+ <td style="width:100%"><div style="width:30px">100%</div></td>
+ <td><div style="width:50px">50px</div><div style="width:50px">50px</div></td>
+ </table>
+ <div style="background:yellow;flex:1 1 auto">auto</div>
+</div>
+
+<h2>Empty table sizes</h2>
+<p class="testdesc">Completely empty table</p>
+<table style="border-spacing: 0px 0px;" data-expected-height=0 data-expected-width=0></table>
+
+<p class="testdesc">Completely empty table with min-content width</p>
+<table style="border-spacing: 0px 0px;width:min-content" data-expected-height=0 data-expected-width=0></table>
+
+
+<p class="testdesc">Completely empty table with max-content width</p>
+<table style="border-spacing: 0px 0px;width:max-content" data-expected-height=0 data-expected-width=0></table>
+
+<p class="testdesc">Completely empty table with width/height</p>
+<table style="border-spacing: 0px 0px;width:50px;height:50px" data-expected-height=50 data-expected-width=50></table>
+
+<p class="testdesc">Empty table with border spacing</p>
+<p class="error">Edge has width</p>
+<table style="border-spacing: 10px 10px;" data-expected-height=0 data-expected-width=0></table>
+
+<p class="testdesc">Table with just tbody and border spacing</p>
+<p class="error">Chrome Legacy has width and 1/2 height. Edge has width. Proposal: make table empty.</p>
+<table style="border-spacing: 10px 10px;" data-expected-height=0 data-expected-width=0>
+ <tbody>
+ </tbody>
+</table>
+
+<p class="testdesc">Table with tbody, tr, and border spacing</p>
+<p class="error">Edge has height, 1/2 width. Chrome Legacy has width/height. Proposal: make table empty.</p>
+<table style="border-spacing: 10px 10px;" data-expected-height=0 data-expected-width=0>
+ <tbody>
+ <tr></tr>
+ </tbody>
+</table>
+
+<p class="testdesc">Empty table with borders</p>
+<p class="error">Edge has width 30, height 20</p>
+<table style="border: 10px solid green" data-expected-height=20 data-expected-width=20></table>
+
+<p class="testdesc">Empty table with padding</p>
+<p class="error">Edge has width 30, height 20</p>
+<table style="padding: 10px" data-expected-height=20 data-expected-width=20></table>
+
+<p class="testdesc">Empty table with caption</p>
+<table data-expected-height=30 data-expected-width=100><caption><div style="width:100px;height:30px">caption</div></caption></table>
+</main>
+
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-quirks.html b/testing/web-platform/tests/css/css-tables/tentative/table-quirks.html
new file mode 100644
index 0000000000..af2a516c0e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-quirks.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<title>Table quirks</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<meta name="flags" content="ahem">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css" />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://quirks.spec.whatwg.org/#the-table-cell-width-calculation-quirk" />
+<style>
+ table {
+ table-layout: auto;
+ border-spacing: 8px 8px;
+ }
+ td {
+ padding: 20px;
+ background: #BFB;
+ font-size: 10px;
+ box-sizing: border-box;
+ }
+ td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+
+<h1>Tables in quirks mode proposals</h1>
+
+<p><a href="https://quirks.spec.whatwg.org/#the-table-cell-height-box-sizing-quirk">The table cell height box sizing quirk</a></p>
+<table data-expected-height=116>
+ <tr>
+ <td style="height:100px;box-sizing:content-box" data-expected-height=100>100 height</td>
+ </tr>
+</table>
+<table data-expected-height=116>
+ <tr>
+ <td style="height:100px;box-sizing:border-box" data-expected-height=100>100 height</td>
+ </tr>
+</table>
+
+<p><a href="https://quirks.spec.whatwg.org/#the-table-cell-nowrap-minimum-width-calculation-quirk">The table cell nowrap minimum width calculation quirk</a></p>
+<p class="error">Chrome Legacy, Edge, Safari fail, only FF gets it correct.<b>Proposal: deprecate the quirk</b></p>
+<table>
+ <tr>
+ <td nowrap style="width:50px;font: 20px/1 Ahem" data-expected-width=580>nowrap nowrap nowrap nowrap</td>
+ </tr>
+</table>
+
+<p><a href="https://quirks.spec.whatwg.org/#the-text-decoration-doesnt-propagate-into-tables-quirk">The text decoration doesn’t propagate into tables quirk</a></p>
+<div style="font-style:italic">
+ <table>
+ <td id="notitalic">decoration</td>
+ </table>
+</div>
+
+<p><a href="https://quirks.spec.whatwg.org/#the-collapsing-table-quirk">The collapsing table quirk</a></p>
+<p class="error">Chrome Legacy/Edge/Safari ignore the quirk, FF does not. <b>Proposal: depreciate the quirk</b></p>
+<table style="border: 20px solid green" data-expected-height=40 data-expected-width=40></table>
+
+<p><a href="https://quirks.spec.whatwg.org/#the-table-cell-width-calculation-quirk">The table cell width calculation quirk</a></p>
+<table style="width:200px">
+ <td data-expected-width=290><img style="width:50px;height:20px"><img style="width:50px;height:20px"><img style="width:50px;height:20px"><img style="width:50px;height:20px"><img style="width:50px;height:20px"></td>
+</table>
+
+<script>
+ let pngSrc="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACWAQMAAAChElVaAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEUAgAD///8UPy9PAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+MBDwkdA1Cz/EMAAAAbSURBVEjH7cGBAAAAAMOg+VPf4ARVAQAAAM8ADzwAAeM8wQsAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDEtMTVUMTc6Mjk6MDMtMDg6MDCYDy9IAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAxLTE1VDE3OjI5OjAzLTA4OjAw6VKX9AAAAABJRU5ErkJggg=="
+;
+ for (let img of Array.from(document.querySelectorAll("img"))) {
+ img.src = pngSrc;
+ }
+ test(_ => {
+ assert_equals(window.getComputedStyle(document.querySelector("#notitalic")).fontStyle, "normal");
+ }, "decoration does not propagate into table");
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed-padding.html b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed-padding.html
new file mode 100644
index 0000000000..097ddacfc3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed-padding.html
@@ -0,0 +1,267 @@
+<!doctype html>
+<title>Columns widths fixed + padding</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns" />
+<style>
+ body {
+ background: #EEE;
+ }
+ main table {
+ background: gray;
+ border-spacing: 8px 8px;
+ table-layout: fixed;
+ }
+ main td {
+ padding: 6px;
+ background: #BFB;
+ font-size: 10px;
+ box-sizing:content-box;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+<main>
+<h1>Fixed tables with padding: Compute column computed widths from assignable table width</h1>
+
+<p>This test is the similar to table-width-redistribution-fixed.html,
+ except that all cells have 6px padding. The comments in this test refer to padding incompatibilities only.</p>
+
+<p class="error">Percentage sizes and box-sizing are handled differently in FF/Chrome. In Chrome, %ge size is always treated as border-box size: column width = % * table width. In FF, box-sizing:content-box, %ge size is % * table width + border_padding, box-sizing:border-box same as Chrome. </p>
+
+<h2>Fixed only</h2>
+
+<p 3 class="testdesc">Table: 50px; C0:100/50/100 C1:100/50/100
+When table.css_width is < columns.css_width, how is the conflict resolved?
+columns.css_width wins
+<p class="error">
+<table style="width:50px" data-expected-width=248>
+ <tr>
+ <td style="width:100px" data-expected-width=112>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=112>
+ <div style="width:50px">50</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<p 4 class="testdesc">Table: 300px; C0:100/100/200 C1:100/90/115
+When table.css_width is > columns.css_width , how is the conflict resolved?
+table.css_width wins</p>
+<table style="width:300px" data-expected-width=300>
+ <tr>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:100px">100</div><div style="width:100px">100</div></td>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:90px">90</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<p 5 class="testdesc">Table: 300px; C0:100/50/50 C1:100/100/100
+Fixed cells must grow, but their min widths differ.
+Fixed cells grow in proportion to their css width.
+<table style="width:calc(300px + 24px)" data-expected-width=324>
+ <tr>
+ <td style="width:100px" data-expected-width=150>
+ <div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=150>
+ <div style="width:100px">100</div></td>
+ </tr>
+</table>
+
+<p 6 class="testdesc">Table: 50px; C0:100/50/50 C1:100/100/100
+What happens when column.min_width > column.css_width
+column.css_width wins over column.min_width.
+<table style="width:100px" data-expected-width=248>
+ <tr>
+ <td style="width:100px" data-expected-width=112>
+ <div style="width:200px"></div></td>
+ <td style="width:100px" data-expected-width=112>
+ <div style="width:200px"></div></td>
+ </tr>
+</table>
+
+<p 7 class="testdesc">Table: 1px.
+What happens to min_width when multiple cells specify css_width of the same column?
+1st cell wins.
+<table style="width:1px" data-expected-width=128>
+ <tr>
+ <td style="width:100px" data-expected-width=112>
+ <div style="width:200px">200</div></td>
+ </tr>
+ <td style="width:150px" data-expected-width=112>
+ <div style="width:150px">150</div></td>
+ </tr>
+</table>
+
+
+<h2>Colspan distribution</h2>
+
+<p 9 class="testdesc">Table: 1px
+Does column.min_width change with colspan distribution from later rows to first row?
+No
+<table style="width:1px" data-expected-width=86>
+ <tr>
+ <td data-expected-width=0>
+ <div style="width:50px"></div></td>
+ <td style="width:50px" data-expected-width=62>
+ <div style="width:50px"></div></td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:200px" data-expected-width=70>
+ <div style="width:200px"></div></td>
+ </tr>
+</table>
+
+
+<h2>Colspan header cells</h2>
+<section>
+<ol>
+ <li>Fixed/percentage colspan cells get distributed evenly.</li>
+ <li>Auto cells. Is the table even fixed?</li>
+</ol>
+
+<p 12 class="testdesc">Assi: 300px
+To make CO distributable width 100, declare it as 100px+8px spacing - 12px padding.
+To make C1 distributable width 200, declare it as 220px+8px spacing - 12px padding.
+Fixed header cells with colspan get divided evenly.
+</p>
+<p class="error">Legacy chrome does not substract border spacing before distribution</p>
+<table style="width:calc(300px + 40px)" data-expected-width=340>
+ <tr>
+ <td colspan=2 style="width:96px" data-expected-width=108>108</td>
+ <td colspan=2 style="width:196px" data-expected-width=208>208</td>
+ </tr>
+ <tr>
+ <td data-expected-width=50>1</td>
+ <td>1</td>
+ <td data-expected-width=100>1</td>
+ <td>1</td>
+ </tr>
+</table>
+
+<p 13 class="testdesc">Assignable: 400px, C0:40% C1:20% C2:40%
+Percentage header cells with colspan.
+Colspan cells do not distribute border_padding, they just distribute widths.
+C0/1/2/3 will not have border-padding becaouse of colspan, C4 because border-box
+TD0 splits
+C0/1 get 20% max (40 + padding)/ 2 = 22px,
+C2/3 10% and (20 + padding) / 2 = 12px max,
+C4 40%, 12px percent border padding, and 52 max
+
+Assignable width is 440 - 48, everyone gets according to percent.
+C0/C1 get 80, C2/C3 get 40, and C4 gets 160.
+</p>
+<p class="error">Firefox seems to have a rounding error.</p>
+<table style="width: calc(400px + 6 * 8px)" data-expected-width=448>
+ <tr>
+ <td colspan=2 style="width:40%" data-expected-width=168><div style="width:40px"></div></td>
+ <td colspan=2 style="width:20%" data-expected-width=88><div style="width:20px"></div></td>
+ <td style="width:40%;box-sizing:border-box" data-expected-width=160><div style="width:40px"></div></td>
+ </tr>
+ <tr>
+ <td data-expected-width=80>Auto</td>
+ <td data-expected-width=80>Auto</td>
+ <td data-expected-width=40>Auto</td>
+ <td data-expected-width=40>Auto</td>
+ <td data-expected-width=160>Auto</td>
+ </tr>
+</table>
+
+<p 14 class="testdesc">Assignable: 1px, C0 Auto/100 colspan=2 , C1 100/Auto
+Auto header cells with colspan, table is min width
+min_width does not get redistributed.
+</p>
+<table style="width:1px" data-expected-width=144>
+ <tr>
+ <td colspan=2 data-expected-width=8>
+ <div style="width:100px">100</div></td>
+ <td style="width:100px" data-expected-width=112>100</td>
+ </tr>
+ <tr>
+ <td data-expected-width=0>x</td>
+ <td data-expected-width=0>x</td>
+ <td data-expected-width=112>x</td>
+ </tr>
+</table>
+
+<p 16 class="testdesc">Assignable: 200; C0: colspan:2 Auto C1:colspan 8 Auto
+Auto colspan cells, and nothing else. Tricky because this means that internally
+table has to represent 10 cells, and wide cells that span beyond table width
+are usually truncated.
+C0: 20*2+8=48, C1: 20*8 + 7*8=216</p>
+<table style="width:calc(200px + 88px)" data-expected-width=288>
+ <tr>
+ <td colspan=2 style="height:20px" data-expected-width=48></td>
+ <td colspan=8 style="height:20px" data-expected-width=216></td>
+ </tr>
+</table>
+
+<h2>Percentage only</h2>
+
+<p 17 class="testdesc">Assignable: 100px;columns add to 100%, auto width
+Column percent adds to a 100, but because box-sizing is content box,
+Column content size adds up to table width.
+Column border size adds up to table width + padding (36px).
+Columns get scaled down.
+Scaling down is not defined by standard. FF and NG differ by a px (rounding?).
+</p>
+<table style="width:calc(100px + 68px)" data-expected-width=168>
+ <tr>
+ <td style="width:50%" data-expected-width=63>50%</td>
+ <td style="width:30%" data-expected-width=42>30%</td>
+ <td style="width:20%" data-expected-width=31>20%</td>
+ </tr>
+</table>
+
+<p 18 class="testdesc">Assignable: 100px;columns add to 50%, auto width
+Columns grow proportional to percent.
+Slight rounding differences between NG and FF.
+<table style="width:calc(100px + 68px)" data-expected-width=168>
+ <tr>
+ <td style="width:25%" data-expected-width=60>25%</td>
+ <td style="width:15%" data-expected-width=42.5>15%</td>
+ <td style="width:10%" data-expected-width=33>10%</td>
+ </tr>
+</table>
+
+
+<p 19 class="testdesc">Assignable: 100px;columns add to 50%, with min width
+Min width is ignored.
+<table style="width:calc(100px + 68px)" data-expected-width=168>
+ <tr>
+ <td style="width:50%" data-expected-width=63><div style="width:50px">50</div></td>
+ <td style="width:30%" data-expected-width=42><div style="width:50px">50</div></td>
+ <td style="width:20%" data-expected-width=31><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<h2>Percentage/auto/fixed mix</h2>
+
+<p class="testdesc">Assignable: 100px;C0:50% C1:100px
+Clean split
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:50%" data-expected-width=38>50%</td>
+ <td style="width:50px" data-expected-width=62>50px</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 100px;C0:60% C1:60px
+Overconstrained: widths add up to 132.
+Fixed widths get distributed first, percentage takes the rest.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:20%" data-expected-width=9>20%</td>
+ <td style="width:60%" data-expected-width=19>60%</td>
+ <td style="width:60px" data-expected-width=72>60px</td>
+ </tr>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed.html b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed.html
new file mode 100644
index 0000000000..4f7cf8ecb3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution-fixed.html
@@ -0,0 +1,374 @@
+<!doctype html>
+<title>Fixed table final assignable distribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns" />
+<style>
+ main table {
+ background: gray;
+ border-spacing: 8px 8px;
+ table-layout: fixed;
+ }
+ main table:hover { table-layout: auto; } /* useful for comparisons */
+ main td {
+ background: #BFB;
+ font-size: 10px;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ height:10px;
+ }
+</style>
+<main>
+ <h1>Fixed tables: Compute column computed widths from assignable table width</h1>
+<ul>
+ <li>auto columns have a min width of 0. Max width still gets computed.</li>
+ <li>percent columns have a min width of 0.</li>
+ <li>fixed column.min_width is css width. It never changes.</li>
+ <li>fixed column.max_width is max(cells.max_width, css width).</li>
+ <li>colspan header cells distribute
+ <ul>
+ <li>max_width evenly between columns.</li>
+ <li>do not distribute min width</li>
+ <li>percentage evenly between columns</li>
+ </ul>
+ </li>
+</ul>
+
+<h2>Is table treated as fixed?</h2>
+<p class="testdesc">table width:auto is not treated as fixed.</p>
+<table style="table-layout:fixed; width:auto" data-expected-width=324>
+ <tr>
+ <td style="width:200px">200</td>
+ <td><div style="width:100px">min</div></td>
+ </tr>
+</table>
+<p class="testdesc">table width:px is treated as fixed.</p>
+<table style="table-layout:fixed; width:224px" data-expected-width=224>
+ <tr>
+ <td style="width:200px">200</td>
+ <td><div style="width:100px">min</div></td>
+ </tr>
+</table>
+<p class="testdesc">table width:min-content is treated as fixed.</p>
+<table style="table-layout:fixed; width:min-content" data-expected-width=224>
+ <tr>
+ <td style="width:200px">200</td>
+ <td><div style="width:100px">min</div></td>
+ </tr>
+</table>
+
+<h2>Fixed only</h2>
+
+<p class="testdesc">Table: 50px; C0:100/50/100 C1:100/50/75
+When table.css_width is &lt; columns.css_width, how is the conflict resolved?
+columns.css_width wins</p>
+<table style="width:50px" data-expected-width=224>
+ <tr>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:50px">50</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Table: 300px; C0:100/100/200 C1:100/90/115
+When table.css_width is > columns.css_width , how is the conflict resolved?
+table.css_width wins</p>
+<table style="width:300px" data-expected-width=300>
+ <tr>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:100px">100</div><div style="width:100px">100</div></td>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:90px">90</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Table: 300px; C0:100/50/50 C1:100/100/100
+Fixed cells must grow, but their min widths differ.
+Fixed cells grow in proportion to their css width.
+<table style="width:calc(300px + 24px)" data-expected-width=324>
+ <tr>
+ <td style="width:100px" data-expected-width=150>
+ <div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=150>
+ <div style="width:100px">100</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Table: 50px; C0:100/50/50 C1:100/100/100
+What happens when column.min_width > column.css_width
+column.css_width wins over column.min_width.
+<table style="width:100px" data-expected-width=224>
+ <tr>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:200px"></div></td>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:200px"></div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Table: 1px.
+What happens to min_width when multiple cells specify css_width of the same column?
+1st cell wins.
+<table style="width:1px" data-expected-width=116>
+ <tr>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:200px">200</div></td>
+ </tr>
+ <td style="width:150px" data-expected-width=100>
+ <div style="width:150px">150</div></td>
+ </tr>
+</table>
+
+<h2>Auto only</h2>
+
+<p class="testdesc">Width is distributed evenly
+</p>
+<table style="width:548px">
+ <tr>
+ <td data-expected-width=100><div style="width:10px;height:30px"></div></td>
+ <td data-expected-width=100><div style="width:20px;height:30px"></div></td>
+ <td data-expected-width=100><div style="width:30px;height:30px"></div></td>
+ <td data-expected-width=100><div style="width:40px;height:30px"></div></td>
+ <td data-expected-width=100><div style="width:120px;height:30px"></div></td>
+ </tr>
+</table>
+
+<h2>Colspan distribution</h2>
+
+<p class="testdesc">Table: 1px
+Does column.min_width change with colspan distribution from later rows to first row?
+No
+<table style="width:1px" data-expected-width=74>
+ <tr>
+ <td data-expected-width=0>
+ <div style="width:50px"></div></td>
+ <td style="width:50px" data-expected-width=50>
+ <div style="width:50px"></div></td>
+ </tr>
+ <tr>
+ <td colspan=2 style="width:200px" data-expected-width=58>
+ <div style="width:200px"></div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Table: 632px
+Does column.percent change with colspan distribution?
+No.
+<table style="width:632px" data-expected-width=632>
+ <tr>
+ <td data-expected-width=360>
+ <div style="width:50px"></div></td>
+ <td style="width:20%" data-expected-width=120>
+ <div style="width:50px"></div></td>
+ <td style="width:20%" data-expected-width=120></td>
+ </tr>
+ <tr>
+ <td colspan="2" style="width:90%">
+ <div style="width:100px"></div></td>
+ <td>auto</td>
+ </tr>
+</table>
+
+<h2>Colspan header cells</h2>
+<section>
+<ol>
+ <li>Fixed/percentage colspan cells get distributed evenly.</li>
+ <li>Auto cells</li>
+</ol>
+
+<p class="testdesc">Assignable: 400px
+Fixed header cells with colspan.
+Columns divded evenly</p>
+<p class="error">Legacy Chrome is slightly off, something about spacing and wide cells.</p>
+<table style="width:calc(600px + 40px)" data-expected-width=640>
+ <tr>
+ <td colspan=2 style="width:108px" data-expected-width=208>108</td>
+ <td colspan=2 style="width:208px" data-expected-width=408>208</td>
+ </tr>
+ <tr>
+ <td data-expected-width=100>1</td>
+ <td>1</td>
+ <td data-expected-width=200>1</td>
+ <td>1</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 400px, C0:40% C1:20% C2:40%
+Percentage header cells with colspan
+C0 splits into C0.0 and C0.1, 16px each with 20%
+C1 splits into C1.0 and C1.1, 6px each with 10%
+Assignable width is 400, everyone gets according to percent.
+80/80/40/40/160.</p>
+<p class="error">Firefox is slightly off, with C2 taking 6px more. Unknown what math is used to get this answer.</p>
+<table style="width:448px" data-expected-width=448>
+ <tr>
+ <td colspan=2 style="width:40%" data-expected-width=168><div style="width:40px"></div></td>
+ <td colspan=2 style="width:20%" data-expected-width=88><div style="width:160px"></div></td>
+ <td style="width:40%" data-expected-width=160><div style="width:40px"></div></td>
+ </tr>
+ <tr>
+ <td data-expected-width=80>Auto</td>
+ <td data-expected-width=80>Auto</td>
+ <td data-expected-width=40>Auto</td>
+ <td data-expected-width=40>Auto</td>
+ <td data-expected-width=160>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 1px, C0 Auto/100 colspan=2 , C1 100/Auto
+Auto header cells with colspan, table is min width
+min_width does not get redistributed.
+</p>
+<table style="width:1px" data-expected-width=132>
+ <tr>
+ <td colspan=2 data-expected-width=8>
+ <div style="width:100px">100</div></td>
+ <td style="width:100px" data-expected-width=100>100</td>
+ </tr>
+ <tr>
+ <td data-expected-width=0>x</td>
+ <td data-expected-width=0>x</td>
+ <td data-expected-width=100>x</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 200; C0: colspan:2 Auto C1:colspan 8 Auto
+Auto colspan cells, and nothing else. Tricky because this means that internally
+table has to represent 8 cells, and wide cells that span beyond table width
+are usually truncated.
+C0: 20*2+8=48, C1: 20*8 + 7*8=216</p>
+<table style="width:calc(200px + 88px)" data-expected-width=288>
+ <tr>
+ <td colspan=2 style="height:20px" data-expected-width=48></td>
+ <td colspan=8 style="height:20px" data-expected-width=216></td>
+ </tr>
+</table>
+
+<h2>Percentage only</h2>
+
+<p class="testdesc">Assignable: 100px;columns add to 100%, auto width
+Columns are exact percentage size.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:50%" data-expected-width=50>50%</td>
+ <td style="width:30%" data-expected-width=30>30%</td>
+ <td style="width:20%" data-expected-width=20>20%</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 100px;columns add to 50%, auto width
+Columns grow proportional to percent.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:25%" data-expected-width=50>25%</td>
+ <td style="width:15%" data-expected-width=30>15%</td>
+ <td style="width:10%" data-expected-width=20>10%</td>
+ </tr>
+</table>
+
+
+<p class="testdesc">Assignable: 100px;columns add to 50%, with min width
+Min width is ignored.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:50%" data-expected-width=50><div style="width:50px">50</div></td>
+ <td style="width:30%" data-expected-width=30><div style="width:50px">50</div></td>
+ <td style="width:20%" data-expected-width=20><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 100px;columns add to 1000%
+Columns are scaled so they add up to 100%
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:200%" data-expected-width=20><div style="width:50px">50</div></td>
+ <td style="width:300%" data-expected-width=30><div style="width:50px">50</div></td>
+ <td style="width:500%" data-expected-width=50><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+
+
+<h2>Percentage/auto/fixed mix</h2>
+
+<p class="testdesc">Assignable: 100px;C0:50% C1:100px C2: Auto
+C0, C1 get assigned values, C2 fills the rest.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:50%" data-expected-width=50>50%</td>
+ <td style="width:30px" data-expected-width=30>30px</td>
+ <td data-expected-width=20></td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 100px;C0:50% C1:50px
+Clean split
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:50%" data-expected-width=50>50%</td>
+ <td style="width:50px" data-expected-width=50>50px</td>
+ </tr>
+</table>
+
+<p class="testdesc">Assignable: 100px;C0:20% C1:60% C2:60px
+Overconstrained: widths add up to 140.
+Fixed widths get distributed first, percentage takes the rest.
+<table style="width:calc(100px + 32px)" data-expected-width=132>
+ <tr>
+ <td style="width:20%" data-expected-width=10>20%</td>
+ <td style="width:60%" data-expected-width=30>60%</td>
+ <td style="width:60px" data-expected-width=60>60px</td>
+ </tr>
+</table>
+
+<h2>Fixed 0-width columns</h2>
+<p>Fixed 0-width columns are an exception. They are treated as a mix of fixed and auto columns.</p>
+ <li>If there are only zero-width columns, width is distibuted evenly.</li>
+ <li>If there are any fixed,percentage, or auto columns, 0-width columns do not grow.</li>
+<p class="testdesc">Assignable: 100px;C0:0-width, C1:0-width
+ All 0-width columns grow.
+</p>
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:0" data-expected-width=50>0</td>
+ <td style="width:0" data-expected-width=50>0</td>
+ </tr>
+</table>
+<p class="testdesc">Assignable: 100px;C0:0-width, C1:auto
+ 0-width column does not grow.
+</p>
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:0" data-expected-width=0>0</td>
+ <td style="width:auto" data-expected-width=100>0</td>
+ </tr>
+</table>
+<p class="testdesc">Assignable: 100px;C0:0-width, C1:50px
+ 0-width column does not grow.
+</p>
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:0" data-expected-width=0>0</td>
+ <td style="width:50px" data-expected-width=100>0</td>
+ </tr>
+</table>
+<p class="testdesc">Assignable: 100px;C0:0-width, C1:50%
+ 0-width column does not grow.
+</p>
+<table style="width:calc(100px + 24px)" data-expected-width=124>
+ <tr>
+ <td style="width:0" data-expected-width=0>0</td>
+ <td style="width:50%" data-expected-width=100>0</td>
+ </tr>
+</table>
+
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution.html b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution.html
new file mode 100644
index 0000000000..90a89e81a5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/table-width-redistribution.html
@@ -0,0 +1,351 @@
+<!doctype html>
+<title>Auto table final assignable distribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#distributing-width-to-columns" />
+<style>
+ main table {
+ background: gray;
+ border-spacing: 8px 8px;
+ }
+ main td {
+ background: #BFB;
+ font-size: 10px;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+ <main>
+<h1>Compute column computed widths from assignable table width</h1>
+<h2>Test design</h2>
+<p>All examples have border-spacing:8, td.padding:0</p>
+
+<h2>Table css sizing</h2>
+
+<p class="testdesc">Table: 50px; C0:100/50/100 C1:100/50/100
+When table.css_width is < columns.css_width, column.min_width is lower limit.
+<p class="error">
+<table style="width:50px" data-expected-width=124>
+ <tr>
+ <td style="width:100px" data-expected-width=50>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=50>
+ <div style="width:50px">50</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+
+<p class="testdesc">Table: 300px; C0:100/100/200 C1:100/90/115
+When table.css_width is > columns.css_width , how is the conflict resolved?
+table.css_width wins</p>
+<table style="width:300px" data-expected-width=300>
+ <tr>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:100px">100</div><div style="width:100px">100</div></td>
+ <td style="width:100px" data-expected-width=138>
+ <div style="width:90px">90</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<h2>Content sizings: min|max|fit|fill-available</h2>
+
+<p class="testdesc">table width:min-content; C0:Auto/50/100 C1:100/50/75 C2:20%/50/75
+</p>
+<p class="error">Edge treats as max-content.</p>
+<table style="width:min-content" data-expected-width=182>
+ <tr>
+ <td data-expected-width=50>
+ <div style="width:50px" >au</div><div style="width:50px">to</div></td>
+ <td style="width:100px" data-expected-width=50>
+ <div style="width:50px" >fix</div><div style="width:25px">ed</div></td>
+ <td style="width:20%" data-expected-width=50>
+ <div style="width:50px">per</div><div style="width:25px">cent</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">table width:max-content; C0:Auto/50/100 C1:100/50/75 C2:20%/50/75
+Each column gets maximum width.
+C0: 100 C1:100 C2: 75
+max-content does not allow for assignable size to be influenced by inverse percent.
+Table size is 275 + 32 = 307
+If percent influenced table size, table size would have been 407
+</p>
+<table style="width:max-content" data-expected-width=307>
+ <tr>
+ <td data-expected-width=120>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:50px">50</div><div style="width:25px">25</div></td>
+ <td style="width:20%" data-expected-width=55>
+ <div style="width:50px">50</div><div style="width:25px">25</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">table width:fit-content; C0:Auto/50/100 C1:100/50/75 C2:20%/50/75
+Percent column determines assignable table width, which gets distributed to all columns.
+Assignable width from %: 20%=75, 100%=375</p>
+</p>
+<table style="width:fit-content" data-expected-width=407>
+ <tr>
+ <td data-expected-width=200>
+ <div style="width:50px" >au</div><div style="width:50px">to</div></td>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:50px" >fix</div><div style="width:25px">ed</div></td>
+ <td style="width:20%" data-expected-width=75>
+ <div style="width:50px">per</div><div style="width:25px">cent</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">table width:-webkit-fill-available; C0:Auto/50/100 C1:100/50/75 C2:20%/50/75
+</p>
+<p class="error">Edge treats as fit-content</p>
+<div style="width:632px">
+<table style="width:-webkit-fill-available;width:-moz-available;" data-expected-width=632>
+ <tr>
+ <td data-expected-width=380>
+ <div style="width:50px" >au</div><div style="width:50px">to</div></td>
+ <td style="width:100px" data-expected-width=100>
+ <div style="width:50px" >fix</div><div style="width:25px">ed</div></td>
+ <td style="width:20%" data-expected-width=120>
+ <div style="width:50px">per</div><div style="width:25px">cent</div></td>
+ </tr>
+</table>
+</div>
+
+<h2>Auto columns distribution</h2>
+
+<p class="testdesc">Assi:300px C0: Auto/75/75 C1:Auto/25/25
+Non-empty auto cells get surplus width proportionally to their max width.
+Guess3: 100. Guess4: 300, diff 200, fixed priority.
+C0: 75 + 75/100*200 = 225 C1: 25 + 25/100*200 = 75</p>
+<table style="width:calc(300px + 24px)" data-expected-width=324>
+ <tr>
+ <td data-expected-width=225><div style="width:75px">75</div></td>
+ <td data-expected-width=75><div style="width:25px">25</div></td>
+ </tr>
+</table>
+<p class="testdesc">Assignable:300px C0: Auto/75/75 C1:Auto/13/25 C2:Auto/0/0
+Empty cells get nothing if there are non-empty auto cells.
+Guess3: 100, Guess4: 300; diff 200, fixed priority.
+C0: 75 + 75/100*200 = 225 C1: 25 + 25/100*200 = 75; C2: 0
+</p>
+<table style="width:calc(300px + 32px)" data-expected-width=332>
+ <tr>
+ <td data-expected-width=225>
+ <div style="width:75px">75</div></td>
+ <td data-expected-width=75>
+ <div style="width:13px">13</div><div style="width:12px">12</div></td>
+ <td data-expected-width=0></td>
+ </tr>
+</table>
+
+<h2>Guess 0: Auto(min), Fixed(min), Percentage(min) to Guess 1.</h2>
+
+<p class="testdesc">Assi: 1px; C0:Auto/50/100 C1:100/50/100 C2:50%/50/100
+All columns get minimum width.
+Guess0: 150
+C0: 50, C1:50, C2: 50</p>
+<table style="width:1px" data-expected-width=182>
+ <tr>
+ <td data-expected-width=50>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=50 style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=50 style="width:50%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+</table>
+
+<p class="testdesc">Assi: 160px; C0:Auto/50/100 C1:100/50/100 C2:50%/50/100
+%ge column grows.
+Guess0: 150, Guess1: 180; diff 10.
+C0: 50, C1:50, C2: 50 + 10 * 10/10 = 60</p>
+<table style="width:calc(160px + 32px)" data-expected-width=192>
+ <tr>
+ <td data-expected-width=50>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=50 style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=60 style="width:50%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+</table>
+
+<p class="testdesc">Assi: 210px; C0:Auto/50/100 C1:100/50/100 C2:30%/50/100 C3:30%/50/100
+2 %ge columns grow evenly.
+Guess 0: 200, Guess 1: 240, diff 10
+C2: 50 + 10 * 70/140 C3: 50 + 10 * 70/140
+<table style="width:calc(40px + 210px)" data-expected-width=250>
+ <tr>
+ <td data-expected-width=50>
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=50 style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=55 style="width:30%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=55 style="width:30%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+</table>
+
+<p class="testdesc">Assi: 220px; C0:Auto/50/100 C1:100/50/100 C2:25%/50/100 C3:40%50/100
+%ge columns grow in proportion to increase from previous guess.
+Guess 0: 200. C2[G1] = .25*220 = 55 C3[G1] = .4 * 220 = 88 Guess 1: 100 + 55 + 88 = 243
+diff = 220 - 200 = 20. C2 grew 5, C3 grew 38, total grew 43.
+C2: 50 + 20 *5/43 = 52.32; C3: 50 + 20 * 38 / 43 = 67.67
+<table style="width:calc(40px + 220px)" data-expected-width=260>
+ <tr>
+ <td data-expected-width=50>
+ <div style="width:50px">50</div> <div style="width:50px">50</div></td>
+ <td data-expected-width=50 style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=52 style="width:25%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width=68 style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+</table>
+
+<h2>Guess 1 to Guess 2: Auto(min), Percentage(%max) to Fixed(min => max)</h2>
+<p>These tests are non-intuitive to evaluate. When table size increases betwee Guess 1 and 2,
+ although the standard says that fixed columns are growing, %ge columns grow too because their max width depends on table width.</p>
+
+<p class="testdesc">Assi:166, C0:Auto/50/100 C1:100/50/100 C2:40%/50/100
+Edge example, Guess 1 %ge cell has grown to the max.
+C2: grows to .4*165 = 66.4, table is 166.4+32 = 198.4</p>
+<table style="width:calc(166px + 32px)" data-expected-width=198>
+ <tr>
+ <td data-expected-width="50" >
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="50" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="66" style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Assi:216, C0:Auto/50/100 C1:100/50/100 C2:40%/50
+ %ge cell grows to the max, the rest goes to fixed.
+Guess 1 size is 50 + 50 + (.4*216=>86.4) = 186.4
+Guess 2 size is 50 + 100 + 86.4 = 236
+Assi - Guess1 = 29.6; C2 = 50 + 29.6 * 50/50 = 79.6
+</p>
+<table style="width:calc(216px + 32px)" data-expected-width=248>
+ <tr>
+ <td data-expected-width="50" >
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="80" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="86" style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<h2>Guess 2 to Guess 3: Percentage(%max), Fixed(max), Auto(min=>max)</h2>
+
+<p class="testdesc">Assi:300
+Guess 2 size is 50 + 100 + .4*300 = 270
+Guess 3 size is 100 + 100 + 120 = 320
+Assi - Guess2 = 30, C0 = 50 + 30 = 80
+<table style="width:calc(300px + 32px)" data-expected-width=332>
+ <tr>
+ <td data-expected-width="80" >
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="100" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="120" style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<h2>Guess3 to Guess4, Auto(max), Percentage(%max), Fixed(max) grow first available Auto|Fixed|Percent</h2>
+
+<p class="testdesc">Assi: 500, C0:Auto, C1: Fixed, C2: Percent
+Guess 3 is 100 + 100 + .4 * 500 = 400
+C0 gets the 100
+<table style="width:calc(500px + 32px)" data-expected-width=532>
+ <tr>
+ <td data-expected-width="200" >
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="100" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="200" style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Assi: 500, C0:Fixed, C1: Fixed, C2: Percent
+Guess 3 is 100 + 100 + .4 * 500 = 400, 100 to be redistributed
+Fixed cells, C0 and C1 get 50 each.
+<table style="width:calc(500px + 32px)" data-expected-width=532>
+ <tr>
+ <td data-expected-width="150" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="150" style="width:100px">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ <td data-expected-width="200" style="width:40%">
+ <div style="width:50px">50</div><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">Assi: 700, C0:10%/40, C1: 20%/50, C2: 40%/50
+Percentage cells only.
+Compute columns as %ge of total width:
+C0: 700*10/70, C1: 700*20/70 C2: 700*40/70
+<table style="width:calc(700px + 32px)" data-expected-width=732>
+ <tr>
+ <td data-expected-width=100 style="width:10%">
+ <div style="width:40px">40</div></td>
+ <td data-expected-width=200 style="width:20%">
+ <div style="width:50px">50</div></td>
+ <td data-expected-width=400 style="width:40%">
+ <div style="width:50px">50</div></td>
+ </tr>
+</table>
+<p class="testdesc">Assi: 600, C0:10%/40, C1: 20%/50, C2: 40%/50, C3: 100%/50
+Percentage cells only. Over 100% columns get their percentage truncated.
+<table style="width:calc(600px + 40px)" data-expected-width=640>
+ <tr>
+ <td data-expected-width=60 style="width:10%">
+ <div style="width:40px">40</div></td>
+ <td data-expected-width=120 style="width:20%">
+ <div style="width:50px">50</div></td>
+ <td data-expected-width=240 style="width:40%">
+ <div style="width:50px">50</div></td>
+ <td data-expected-width=180 style="width:100%">
+ <div style="width:50px">50</div></td>
+ </tr>
+</table>
+<p class="testdesc">C0:20%/60, C1:Auto/50.
+Tests table max width from single cell.
+<table data-expected-width="324">
+ <tr>
+ <td style="width:20%" data-expected-width="60"><div style="width:60px">60</div></td>
+ <td><div style="width:50px">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">C0:10%/70, C1:Auto/50.
+Table limited to 1px. Tests that single cell specifies max width, not min width.
+<table style="width:1px" data-expected-width="134">
+ <tr>
+ <td style="width:20%" data-expected-width="60"><div style="width:60px">60</div></td>
+ <td><div style="width:50px" data-expected-width="50">50</div></td>
+ </tr>
+</table>
+
+<p class="testdesc">C0:10%/70 border 10px, C1:Auto/50.
+Cell border padding do not affect max width.
+<table data-expected-width="524">
+ <tr>
+ <td style="width:20%;border:10px solid yellow;padding:10px" data-expected-width="100"><div style="width:60px">60</div></td>
+ <td><div style="width:50px">50</div></td>
+ </tr>
+</table>
+</main>
+
+<script>
+ checkLayout("table");
+</script>
+
diff --git a/testing/web-platform/tests/css/css-tables/tentative/tbody-height-redistribution.html b/testing/web-platform/tests/css/css-tables/tentative/tbody-height-redistribution.html
new file mode 100644
index 0000000000..bfd47fa651
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/tbody-height-redistribution.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<title>TBODY redistribution</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel='stylesheet' href='../support/base.css' />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#height-distribution-algorithm" />
+<style>
+ main table {
+ border-collapse: collapse;
+ background: #DDD;
+ }
+ main td {
+ padding: 0;
+ }
+ main td .empty {
+ line-height: 0;
+ }
+ main tbody tr:nth-child(1) {
+ background: rgba(255, 156, 0, 0.5);
+ }
+ main tbody tr:nth-child(2) {
+ background: rgba(255, 255, 0, 0.5);
+ }
+ main tbody tr:nth-child(3) {
+ background: rgba(0, 255, 0, 0.5);
+ }
+</style>
+<main>
+<h1>TBODY/THEAD/TFOOT height redistribution.</h1>
+<li>FF passes most of the tests.
+<li>Legacy Chrome does not distribute TBODY height to rows.
+<li>At the time this test was written, there was no spec. Currently, spec is in the process of being written.
+
+<p>1) Empty row group's size is 0 with collapsed borders</p>
+<table id="one" style="border-collapse: collapse;border-spacing: 10px 10px;border:10px solid green"
+ data-expected-width="0" data-expected-height="0">
+ <tbody>
+ <tr> </tr>
+ </tbody>
+</table>
+<p>2) Empty row group's size is 0 with separate borders.</p>
+<table id="two" style="border-collapse: separate;border-spacing: 10px 10px;border:10px solid green"
+ data-expected-width="20" data-expected-height="20">
+ <tbody>
+ <tr> </tr>
+ </tbody>
+</table>
+<p>3) Row group height is redistributed to unconstrained rows in proportion to their size.</p>
+<table id="three">
+ <tbody style="height:100px" data-expected-height="100">
+ <tr data-expected-height="25">
+ <td><div style="height:10px" >0,0</div></td>
+ </tr>
+ <tr data-expected-height="75">
+ <td><div style="height:30px" >0,0</div></td>
+ </tr>
+ </tbody>
+</table>
+<p>4) Constrained fixed rows do not grow if there are unconstrained rows</p>
+<table id="four">
+ <tbody style="height:100px">
+ <tr style="height: 10px" data-expected-height="10">
+ <td></td>
+ </tr>
+ <tr data-expected-height="90">
+ <td>0,1</td>
+ </tr>
+ </tbody>
+</table>
+<p>5) Constrained percentage are resolved against row group height.</p>
+<table id="five">
+ <tbody style="height:100px">
+ <tr style="height:25%" data-expected-height="25">
+ <td>0,0</td>
+ </tr>
+ <tr style="height:50%" data-expected-height="50">
+ <td>0,0</td>
+ </tr>
+ <tr data-expected-height="25">
+ <td>0,2</td>
+ </tr>
+ </tbody>
+</table>
+<p>6) Row group height is treated as min-height.</p>
+<table id="six">
+ <tbody style="height:100px" data-expected-height="125">
+ <tr style="height:125px">
+ <td>0,0</td>
+ </tr>
+ </tbody>
+</table>
+<p>7) Constrained/unconstrained mix: row group height is distributed to unconstrained cells.</p>
+<table id="seven">
+ <tbody style="height:100px">
+ <tr style="height:20px" data-expected-height="20"><td>0,0</td></tr>
+ <tr style="height:30px" data-expected-height="30"><td>0,1</td></tr>
+ <tr data-expected-height="25"><td>0,2</td></tr>
+ <tr data-expected-height="25"><td>0,3</td></tr>
+ </tbody>
+</table>
+<p>8) Unconstrained empty rows grow to fill table if all other rows are constrained. Not in FF.</p>
+<table id="eight">
+ <tbody style="height:100px">
+ <tr style="height:20px" data-expected-height="20"><td>0,0</td></tr>
+ <tr style="height:30px" data-expected-height="30"><td>0,1</td></tr>
+ <tr data-expected-height="50"><td></td></tr>
+ </tbody>
+</table>
+<br>
+<table id="eightplus">
+ <tbody style="height:100px">
+ <tr data-expected-height="50"><td></td></tr>
+ <tr style="height:20px" data-expected-height="20"><td>0,1</td></tr>
+ <tr style="height:30px" data-expected-height="30"><td>0,2</td></tr>
+ </tbody>
+</table>
+<p>9) Empty section height is not ignored</p>
+<table id="nine" >
+ <tbody style="height:75px" data-expected-height="75">
+ </tbody>
+</table>
+<p>10) Section with empty rows is not considered empty.</p>
+<p>In FF, empty section height is 100, but table's height is 0?</p>
+<table id="nine" >
+ <tbody style="height:75px" data-expected-height="75">
+ <tr data-expected-height="25"></tr>
+ <tr data-expected-height="25"></tr>
+ <tr data-expected-height="25"></tr>
+ </tbody>
+</table>
+<p>11) Mixed constrained and unconstrained empty rows: only unconstrained rows grow.</p>
+ <table id="ten" style="width:50px">
+ <tbody style="height:50px" data-expected-height="50">
+ <tr style="height:0" data-expected-height="0"><td></td></tr>
+ <tr data-expected-height="25"><td></td></tr>
+ <tr data-expected-height="25"><td></td></tr>
+ </tbody>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-001.html b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-001.html
new file mode 100644
index 0000000000..b54eb39f58
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-001.html
@@ -0,0 +1,197 @@
+<!doctype html>
+<title>TD box sizing</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="stylesheet" type="text/css" href="./support/table-tentative.css">
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/" />
+<style>
+ main table {
+ background: gray;
+ border-spacing: 10px 10px;
+ table-layout: auto;
+ }
+ main td {
+ padding: 20px;
+ background: #BFB;
+ font-size: 10px;
+ box-sizing: border-box;
+ }
+ main td > div {
+ display: inline-block;
+ background: rgba(56,162,56,0.3);
+ }
+</style>
+<main>
+<h1>TD and box sizing</h1>
+
+<p>TD defaults to box-sizing: content-box. How does box-sizing affect final TD size?</p>
+<ol>
+ <li>Auto table layout</li>
+ <ol>
+ <li>Percent cells ignore box-sizing, it is always border-box.</li>
+ <li>Fixed cells respect box-sizing.</li>
+ </ol>
+ <li>Fixed table layout</li>
+ <ol>
+ <li>Percent cells respect box sizing when computing cell width from assignable width.</li>
+ <li>Percent cells ignore box sizing when computing grid max from cell width.</li>
+ </ol>
+</ol>
+<h2>Table-layout: auto</h2>
+<h4>TD width:%</h4>
+<p class="testdesc">content-box, C0:50%/100 C1:Auto
+Percent gets resolved to compute grid max size.
+C0 max_width is max_width + 2 padding = 100 + 2*20 = 140
+Table width is 1/50%*140 + 3*padding = 280+30 = 310
+<table data-expected-width=310>
+ <tr>
+ <td style="width:50%;box-sizing:content-box" data-expected-width=140>
+ <div style="width:100px">50%/100</td>
+ <td data-expected-width=140>Auto</td>
+ </tr>
+</table>
+<p class="testdesc">border-box, C0:50%/100 C1:Auto
+Same test as above, but box-sizing is border-box.
+<table data-expected-width=310>
+ <tr>
+ <td style="width:50%;box-sizing:border-box" data-expected-width=140>
+ <div style="width:100px">50%/100</td>
+ <td data-expected-width=140>Auto</td>
+ </tr>
+</table>
+<p class="testdesc">content-box, C0:80%/100 C1:Auto
+Percent gets resolved to compute final cell size from assignable width.
+C0 border box width is 500 * 80%
+<table style="width:530px" data-expected-width=530>
+ <tr>
+ <td style="width:80%;box-sizing:content-box" data-expected-width=400>
+ <div style="width:100px">80%/100</td>
+ <td data-expected-width=100>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">border-box, C0:80%/100 C1:Auto
+Same as above, but border-box
+<table style="width:530px" data-expected-width=530>
+ <tr>
+ <td style="width:80%;box-sizing:border-box" data-expected-width=400>
+ <div style="width:100px">80%/100</td>
+ <td data-expected-width=100>Auto</td>
+ </tr>
+</table>
+
+
+<h4>TD width:fixed</h4>
+
+<p class="testdesc">content-box, C0:100/Auto C1:100/Auto
+Tests whether box-sizing affects how percentages are computed.
+C0 max_width is max_width + 2 padding = 100 + 2*20 = 140
+Table width is 1/50%*140 + 3*padding = 280+30 = 310
+<table data-expected-width=310>
+ <tr>
+ <td style="width:100px;box-sizing:content-box" data-expected-width=140>100</td>
+ <td style="width:100px;box-sizing:content-box">100</td>
+ </tr>
+</table>
+
+<p class="testdesc">border-box, C0:100/Auto C1:100/Auto
+Same test as above, but box-sizing is border-box.
+<table data-expected-width=230>
+ <tr>
+ <td style="width:100px;box-sizing:border-box" data-expected-width=100>100</td>
+ <td style="width:100px;box-sizing:border-box" data-expected-width=100>100</td>
+ </tr>
+</table>
+
+<h4>TD height: fixed</h4>
+
+<p class="testdesc">content-box, C0 height:100px
+<table data-expected-height=160>
+ <tr>
+ <td style="height:100px;box-sizing:content-box" data-expected-height=140>100 height</td>
+ </tr>
+</table>
+
+<p class="testdesc">border-box, C0 height:100px
+<table data-expected-height=120>
+ <tr>
+ <td style="height:100px;box-sizing:border-box" data-expected-height=100>100 height</td>
+ </tr>
+</table>
+
+<h2>Table-layout: fixed</h2>
+
+<h4>TD width:%</h4>
+
+<p class="testdesc">content-box, C0:50%/100 C1:Auto
+Percent gets resolved to compute grid max size.
+C0 max_width is max_width + 2 padding = 100 + 2*20 = 140
+Table width is 1/50%*140 + 3*padding = 280+30 = 310
+<table style="table-layout:fixed" data-expected-width=310>
+ <tr>
+ <td style="width:50%;box-sizing:content-box" data-expected-width=140>
+ <div style="width:100px">50%/100</td>
+ <td data-expected-width=140>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">border-box, C0:50%/100 C1:Auto
+Same test as above, but box-sizing is border-box.
+<table style="table-layout:fixed" data-expected-width=310>
+ <tr>
+ <td style="width:50%;box-sizing:border-box" data-expected-width=140>
+ <div style="width:100px">50%/100</td>
+ <td data-expected-width=140>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">content-box, C0:60%/100 C1:Auto
+Percent gets resolved to compute final cell size from assignable width.
+Assignable width is 530 - 3*10 = 500
+C0 content box width is 500 * 60% + 40px padding = 340
+C1 is 500 - 340 = 160
+<p class="error">Legacy/Edge treat %ge TD as border box, and end up with 300px</p>
+<table style="table-layout:fixed;width:530px" data-expected-width=530>
+ <tr>
+ <td style="width:60%;box-sizing:content-box" data-expected-width=340>
+ <div style="width:100px">60%/100</td>
+ <td data-expected-width=160>Auto</td>
+ </tr>
+</table>
+
+<p class="testdesc">border-box, C0:60%/100 C1:Auto
+Same as above, but border-box
+<table style="table-layout:fixed;width:530px" data-expected-width=530>
+ <tr>
+ <td style="width:60%;box-sizing:border-box" data-expected-width=300>
+ <div style="width:100px">80%/100</td>
+ <td data-expected-width=200>Auto</td>
+ </tr>
+</table>
+
+
+<h4>TD width:fixed</h4>
+<p class="testdesc">content-box, C0:100/Auto C1:100/Auto
+Tests whether box-sizing affects how percentages are computed.
+C0 max_width is max_width + 2 padding = 100 + 2*20 = 140
+Table width is 1/50%*140 + 3*padding = 280+30 = 310
+<table style="table-layout:fixed" data-expected-width=310>
+ <tr>
+ <td style="width:100px;box-sizing:content-box" data-expected-width=140>100</td>
+ <td style="width:100px;box-sizing:content-box">100</td>
+ </tr>
+</table>
+<p class="testdesc">border-box, C0:100/Auto C1:100/Auto
+Same test as above, but box-sizing is border-box.
+<table style="table-layout:fixed" data-expected-width=230>
+ <tr>
+ <td style="width:100px;box-sizing:border-box" data-expected-width=100>100</td>
+ <td style="width:100px;box-sizing:border-box" data-expected-width=100>100</td>
+ </tr>
+</table>
+</main>
+<script>
+ checkLayout("table");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-002.html b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-002.html
new file mode 100644
index 0000000000..5823fc64c6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-002.html
@@ -0,0 +1,123 @@
+<!doctype html>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://www.w3.org/TR/css-tables-3/#computing-the-table-width" />
+<style>
+ .t {
+ display: table;
+ border-top-width: 20px;
+ border-bottom-width: 40px;
+ border-left-width: 20px;
+ border-right-width: 40px;
+ border-style: solid;
+ border-color: gray;
+ padding: 10px;
+ border-spacing: 0;
+ width:100px;
+ height: 100px;
+ }
+ .inline {
+ display: inline-table;
+ }
+ .cell {
+ display: table-cell;
+ background: yellow;
+ }
+ main td {
+ padding: 0;
+ background: yellow;
+ }
+</style>
+<main>
+<p>box-sizing: default; border-collapse: separate </p>
+<table class="t" style="border-collapse: separate" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>box-sizing: border-box; border-collapse: separate</p>
+<table class="t" style="box-sizing:border-box;border-collapse: separate" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>box-sizing: content-box; border-collapse: separate</p>
+<table class="t" style="box-sizing:content-box;border-collapse: separate" data-expected-width="180" data-expected-height="180">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>box-sizing: default; border-collapse: collapse </p>
+<table class="t" style="border-collapse: collapse" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>box-sizing: border-box; border-collapse: collapse</p>
+<table class="t" style="box-sizing:border-box;border-collapse: collapse" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>box-sizing: content-box; border-collapse: collapse</p>
+<table class="t" style="box-sizing:content-box;border-collapse: collapse" data-expected-width="130" data-expected-height="130">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>
+<p>div with display:table; box-sizing: default; border-collapse: separate</p>
+<div class="t" style="border-collapse: separate" data-expected-width="180" data-expected-height="180">
+ <div class="cell"></div>
+</div>
+<p>div with display:table; box-sizing: border-box; border-collapse: separate</p>
+<div class="t" style="box-sizing:border-box;border-collapse: separate" data-expected-width="100" data-expected-height="100">
+ <div class="cell"></div>
+</div>
+<p>div with display:table;box-sizing: content-box; border-collapse: separate</p>
+<div class="t" style="box-sizing:content-box;border-collapse: separate" data-expected-width="180" data-expected-height="180">
+ <div class="cell"></div>
+</div>
+
+<h2>Same tests, but tables are inline.</h2>
+<div>
+<table class="t inline" style="box-sizing:border-box;border-collapse: separate" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>box-sizing: border-box; border-collapse: separate
+
+<div>
+<table class="t inline" style="box-sizing:content-box;border-collapse: separate" data-expected-width="180" data-expected-height="180">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>box-sizing: content-box; border-collapse: separate</div>
+<div>
+<table class="t inline" style="box-sizing:border-box;border-collapse: collapse" data-expected-width="100" data-expected-height="100">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>box-sizing: border-box; border-collapse: collapse</div>
+<div>
+<table class="t inline" style="box-sizing:content-box;border-collapse: collapse" data-expected-width="130" data-expected-height="130">
+ <tbody>
+ <td></td>
+ </tbody>
+</table>box-sizing: content-box; border-collapse: collapse</div>
+<div>
+<div class="t inline" style="box-sizing:border-box;border-collapse: separate" data-expected-width="100" data-expected-height="100">
+ <div class="cell"></div>
+</div>
+div with display:inline-table; box-sizing: border-box;
+</div>
+<div>
+<div class="t inline" style="box-sizing:content-box;border-collapse: separate" data-expected-width="180" data-expected-height="180">
+ <div class="cell"></div>
+</div>
+div with display:inline-table;box-sizing: content-box</div>
+</main>
+<script>
+ checkLayout(".t");
+</script>
diff --git a/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-003.html b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-003.html
new file mode 100644
index 0000000000..40b01471fd
--- /dev/null
+++ b/testing/web-platform/tests/css/css-tables/tentative/td-box-sizing-003.html
@@ -0,0 +1,148 @@
+<!doctype html>
+<title>TD box sizing</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src="/resources/check-layout-th.js"></script>
+<link rel='stylesheet' href='../support/base.css' />
+<link rel='stylesheet' href='/fonts/ahem.css' />
+<link rel="author" title="Aleks Totic" href="atotic@chromium.org" />
+<link rel="help" href="https://drafts.csswg.org/css-tables-3/#computing-cell-measures" />
+<style>
+ main table {
+ border-spacing: 0;
+ }
+ main td {
+ background: gray;
+ width:100px;
+ padding: 0;
+ }
+ .bb {
+ box-sizing: border-box;
+ }
+</style>
+<main>
+<p>Tests of intrinsic cell sizing wrt border/padding, and box-sizing.</p>
+<p>box-sizing: content-box; border px; padding px.
+<table>
+ <tbody>
+ <tr>
+ <td data-expected-width="100">
+ <div style="width:50px;height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<table>
+ <tbody>
+ <tr data-expected-width="120">
+ <td data-expected-width="120" style="border:10px solid black">
+ <div style="height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<table>
+ <tbody>
+ <tr data-expected-width="140">
+ <td data-expected-width="140" style="border:10px solid black;padding: 10px">
+ <div style="height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>box-sizing: border-box, border px, padding px.
+<table>
+ <tbody>
+ <tr>
+ <td data-expected-width="100" class="bb">
+ <div style="height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<table>
+ <tbody>
+ <tr>
+ <td data-expected-width="100" class="bb" style="border:10px solid black" >
+ <div style="height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<table>
+ <tbody>
+ <tr>
+ <td data-expected-width="100" class="bb" style="border:10px solid black;padding: 10px">
+ <div style="height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>box-sizing: border-box;padding: px, width px</p>
+<li>td's intrinsic width must be >= border + padding</li>
+
+<table style="width:300px;table-layout:fixed">
+ <tbody>
+ <tr>
+ <td style="box-sizing:border-box;padding-left:50px;padding-right:50px;width:30px" data-expected-width=100></td>
+ <td>auto</td>
+ <td>auto</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>box-sizing: border-box; border px; padding %.</p>
+<li>intrinsic size of % padding is 0.
+<li>final size of % padding is computed against table's width.
+<table data-expected-width="240">
+ <tbody>
+ <tr>
+ <td data-expected-width="120" style="border:10px solid black;padding: 30%">
+ <div data-offset-x="72" data-offset-y="72" style="width:50px;height:50px;background:yellow">0,0</div>
+ </td>
+ <td style="border:10px solid black;padding: 30%">
+ <div style="width:50px;height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<table data-expected-width="300">
+ <caption><div style="width:300px;background:#ddd">300px caption</div></caption>
+ <tbody>
+ <tr>
+ <td data-expected-width="150" style="border:10px solid black;padding: 30%">
+ <div data-offset-x="90" data-offset-y="90" style="width:50px;height:50px;background:yellow">0,0</div>
+ </td>
+ <td style="border:10px solid black;padding: 30%">
+ <div style="width:50px;height:50px;background:yellow">0,0</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Block percentage resolution of TD children + row fixed height during intrinsic pass</p>
+<li>Chrome Legacy/Edge/Safari do not use row fixed height for percetage block size resolution.</li>
+<li>FF uses row height as %ge resolution size.</li>
+<li>Proposal: file an issue on what is the right thing to do.</li>
+<table>
+ <tr>
+ <td style="height:100px;font: 50px/1 Ahem;" id="cell" data-expected-height="100">
+ y<div style="display:inline-block;height:100%;width:50px;background:yellow"
+ data-expected-height="100"></div>
+ </td>
+ </tr>
+</table>
+<table>
+ <tr style="height:100px">
+ <td style="font: 50px/1 Ahem;" id="cell" data-expected-height="100">
+ y<div style="display:inline-block;height:100%;width:50px;background:yellow" data-expected-height="0"></div>
+ </td>
+ </tr>
+</table>
+
+
+</main>
+<script>
+ checkLayout("table");
+</script>