-
Notifications
You must be signed in to change notification settings - Fork 672
/
Overview.bs
3433 lines (2830 loc) · 172 KB
/
Overview.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
Title: CSS Table Module Level 3
Shortname: css-tables
Level: 3
Status: ED
Work Status: Exploring
Group: csswg
ED: https://drafts.csswg.org/css-tables-3/
TR: https://www.w3.org/TR/css-tables-3/
Previous Version: https://www.w3.org/TR/2019/WD-css-tables-3-20190727/
Previous Version: https://www.w3.org/TR/CSS2/tables.html
Repository: w3c/csswg-drafts
Warning: not ready
Editor: François Remy, Invited Expert, w3cid 53348
Editor: Greg Whitworth, Microsoft, w3cid 69511
Former editor: Bert Bos, W3C
Former editor: L. David Baron, Mozilla https://www.mozilla.org/, https://dbaron.org/, w3cid 15393
Former editor: Markus Mielke, Microsoft
Former editor: Saloni Mira Rai, Microsoft
Abstract: This CSS module defines a two-dimensional grid-based layout system, optimized for tabular data rendering. In the table layout model, each display node is assigned to an intersection between a set of consecutive rows and a set of consecutive columns, themselves generated from the table structure and sized according to their content.
Ignored Terms: block-level box
</pre>
<!-- NOTE TO SELF:
BEFORE PUBLISHING A NEW WORKING DRAFT:
- switch Status to WD
- search the w3c list archives for the wg resolution allowing to republish
- fix all the linting issues
AFTER PUBLISHING A NEW WORKING DRAFT:
- revert Status to ED
- update Previous Version to the permalink of the new version you pushed
- commit those changes to csswg-drafts
-->
<pre class=link-defaults>
spec:css-sizing-3; type:property; text:min-height
spec:css-sizing-3; type:property; text:min-width
spec:css-sizing-3; type:property; text:max-width
spec:css2; type:property; text:top
spec:css2; type:property; text:right
spec:css2; type:property; text:bottom
spec:filter-effects-1; type:property; text:filter
spec:css-sizing-3; type:property; text:box-sizing
</pre>
<!--
████ ██ ██ ████████ ████████ ███████
██ ███ ██ ██ ██ ██ ██ ██
██ ████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ████████ ██ ██
██ ██ ████ ██ ██ ██ ██ ██
██ ██ ███ ██ ██ ██ ██ ██
████ ██ ██ ██ ██ ██ ███████
-->
<h2 id="intro">Introduction</h2>
<em>This section is not normative</em>
Many types of information (ex: weather readings collected over the past year)
are best visually represented in a two-axis grid
where rows represent one item of the list
(ex: a date, and the various weather properties measured during that day),
and where columns represent the successive values of an item's property
(ex: the temperatures measured over the past year).
Sometimes, to make the representation easier to understand,
some cells of the grid are used to represent a description or summary of their parent row/column,
instead of actual data.
This happens more frequently for
the cells found on the first row and/or column (called headers)
or the cells found on the last row and/or column (called footers).
This kind of tabular data representation is usually known as tables.
Tables layout can be abused to render other grid-like representations like calendars or timelines,
though authors should prefer other layout modes
when the information being represented does not make sense as a data table.
The rendering of tables in HTML has been defined for a long time in the HTML specification.
However, its interactions with features defined in CSS remained for a long time undefined.
The goal of this specification is to define
the expected behavior of user agents supporting both HTML tables and CSS.
Please be aware that some behaviors defined in this document
will not be the most logical or useful way of solving the problem they aim to solve,
but such behaviors are often the result of compatibility requirements and not a deliberate choice
of the editors of this specification.
Authors wishing to use more complex layouts
are encouraged to rely on more modern CSS modules such as CSS Grid.
<h3 id="values">Value Definitions</h3>
This specification follows the <a href="https://www.w3.org/TR/CSS2/about.html#property-defs">CSS property definition conventions</a> from [[!CSS2]]
using the <a href="https://www.w3.org/TR/css-values-3/#value-defs">value definition syntax</a> from [[!CSS-VALUES-3]].
Value types not defined in this specification are defined in CSS Values & Units [[!CSS-VALUES-3]].
Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the <a>CSS-wide keywords</a> as their property value.
For readability they have not been repeated explicitly.
<!--
██████ ███████ ██ ██ ████████ ████████ ██ ██ ████████ ██ ██ ███████ ████████ ████████ ██
██ ██ ██ ██ ███ ██ ██ ██ ███ ██ ██ ███ ███ ██ ██ ██ ██ ██ ██
██ ██ ██ ████ ██ ██ ██ ████ ██ ██ ████ ████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██████ ██
██ ██ ██ ██ ████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ███ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ███████ ██ ██ ██ ████████ ██ ██ ██ ██ ██ ███████ ████████ ████████ ████████
-->
<h2 id="content-model">Content Model</h2>
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="table-structure">Table Structure</h3>
The CSS table model is based on the HTML4 table model,
in which the structure of a table closely parallels the visual layout of the table.
In this model, a table consists of an optional caption and any number of rows of cells.
In addition, adjacent rows and columns may be grouped structurally and
this grouping can be reflected in presentation (e.g., a border may be drawn around a group of rows).
The table model is said to be "row primary" since
authors specify rows, not columns, explicitly in the document language.
Columns are derived once all the rows have been specified:
the first cell of the first row belongs to the first column
and as many other columns as spanning requires (and it creates them if needed),
and the following cells of that row each belong to the next available column
and as many other columns as spanning requires (creating those if needed);
the cells of the following rows each belong to the next available column for that row (taking rowspan into account)
and as many other columns as spanning requires (creating those if needed).
<span class="hint">(see [[#dimensioning-the-row-column-grid]])</span>.
To summarize, an instance of the table model consists of:
<ul class="compact">
<li>Its <a href="#table-root-element">table-root</a> containing:
<ul>
<li>Zero, one or more <a href="#table-row">table rows</a>, optionally in <a href="#table-row-group">row groups</a>,
<ul><li>Each of them containing one or more <a href="#table-cell">table cells</a></li></ul>
<li>Optionally: one or more <a href="#table-column">table columns</a>,
optionally in <a href="#table-column-group">column groups</a>
<li>Optionally: one or more <a href="#table-caption">table caption</a>.
</ul>
</ul>
<style>
ul.compact { margin-top: -1em !important; list-style-type: disc; }
ul.compact li { margin-top: 0 !important; margin-bottom: 0 !important; list-style-type: disc; }
</style>
<figure>
<img alt="[see-caption-below]" src="images/table-structure.png" width=493>
<figcaption>Two representations of the structure of a table (tree vs layout)</figcaption>
</figure>
The CSS model does not require that the document language include elements that correspond to each of these components.
For document languages (such as XML applications) that do not have pre-defined table elements,
authors must map document language elements to table elements.
This is done with the 'display' property.
The following 'display' values assign table formatting rules to an arbitrary element:
<dl id="display-types">
<dt><dfn>table</dfn> (equivalent to HTML: <table>)
<dd>Specifies that an element defines a table
that is <a>block-level</a> when placed in <a>flow layout</a>.
<dt><dfn>inline-table</dfn> (equivalent to HTML: <table>)
<dd>Specifies that an element defines a table
that is <a>inline-level</a> when placed in <a>flow layout</a>.
<dt><dfn>table-row</dfn> (equivalent to HTML: <tr>)
<dd>Specifies that an element is a row of cells.
<dt><dfn>table-row-group</dfn> (equivalent to HTML: <tbody>)
<dd>Specifies that an element groups some amount of rows.
Unless explicitly mentioned otherwise, mentions of [=table-row-groups=] in this spec also encompass the specialized [=table-header-groups=] and [=table-footer-groups=].
<dt><dfn>table-header-group</dfn> (equivalent to HTML: <thead>)
<dd>Like [=table-row-group=] but, for layout purposes,
the first such row group is always displayed before all other rows and row groups.
<div class="advisement">
If a table owns multiple <code>display: table-header-group</code> boxes,
only the first is treated as a header;
the others are treated as if they had <code>display: table-row-group</code>.
</div>
<dt><dfn>table-footer-group</dfn> (equivalent to HTML: <tfoot>)
<dd>Like [=table-row-group=] but, for layout purposes,
the fist such row group is always displayed after all other rows and row groups.
<div class="advisement">
If a table owns multiple <code>display: table-footer-group</code> boxes,
only the first is treated as a footer;
the others are treated as if they had <code>display: table-row-group</code>.
</div>
<dt><dfn>table-column</dfn> (equivalent to HTML: <col>)
<dd>Specifies that an element describes a column of cells.
<dt><dfn>table-column-group</dfn> (equivalent to HTML: <colgroup>)
<dd>Specifies that an element groups one or more columns.
<dt><dfn>table-cell</dfn> (equivalent to HTML: <td> or <th>)
<dd>Specifies that an element represents a table cell.
<dt><dfn>table-caption</dfn> (equivalent to HTML: <caption>)
<dd>Specifies a caption for the table.
Table captions are positioned between the table margins and its borders.
</dl>
Note: [=Replaced elements=] with a 'display' value of
''table-row'',
''table-row-group '',
''table-header-group'',
''table-footer-group'',
''table-column'',
''table-column-group'',
''table-cell'',
and ''table-caption''
are treated as [=inline-level boxes=],
as per [[css-display-3#layout-specific-display]];
[=replaced elements=] with a 'display' value of ''table'' or ''inline-table''
behave according to their [=outer display type=],
as per [[css-display-3#outer-role]].
<strong>This is a breaking change from CSS 2.1 but matches implementations.</strong>
<h4 id="terminology">Terminology</h2>
In addition to the table structure display types,
the following wording is also being used in this spec:
<dl export>
<dt><dfn lt="table wrapper box | table-wrapper box" local-lt="table-wrapper">table wrapper box</dfn>
<dd>
A block container box <a href="#fixup-algorithm">generated around table grid boxes</a>
to account for any space occupied by each <a>table-caption</a> it owns.
<dt><dfn lt="table grid box | table-grid box" local-lt="table-grid">table grid box</dfn>
<dd>
A block-level box containing the table-internal boxes, excluding its captions.
<dt><dfn id="table-root-element">table-root</dfn> element
<dd>
An element whose <a>inner display type</a> is ''display/table''.
<dt><dfn id="table-non-root-element">table-non-root</dfn> box or element
<dd>
A <a>proper table child</a>, or a <a>table-cell</a> box.
<dt><dfn id="table-track">table-track</dfn> box or element
<dd>
A
<a>table-row</a>, or
<a>table-column</a> box.
<dt><dfn id="table-track-group-element">table-track-group</dfn> box or element
<dd>
A
<a>table-row-group</a>, or
<a>table-column-group</a> box.
<dt><dfn id="proper-table-child-element">proper table child</dfn> box or element
<dd>
A
<a>table-track-group</a>,
<a>table-track</a>, or
<a>table-caption</a> box.
<dt><dfn id="proper-table-row-parent-element">proper table-row parent</dfn> box or element
<dd>
A <a>table-root</a> or a <a>table-row-group</a> box.
<dt><dfn id="table-internal-element">table-internal</dfn> box or element
<dd>
A <a>table-cell</a>, <a>table-track</a> or <a>table-track-group</a> box.
<dt><dfn id="tabular-container">tabular container</dfn>
<dd>
A <a>table-row</a> or <a>proper table-row parent</a> box.
<dt><dfn noexport id="consecutive-boxes">consecutive</dfn> boxes
<dd>
Two sibling boxes are consecutive
if they have no intervening siblings
other than, optionally, an anonymous inline containing only white spaces.
A sequence of sibling boxes is consecutive
if each box in the sequence is consecutive to the one before it in the sequence.
<dt><dfn id="table-grid">table grid</dfn>
<dd>
A matrix
containing as many <dfn id="row">rows</dfn> and <dfn id="column">columns</dfn>
as needed to describe the position of all the <a>table-rows</a> and <a>table-cells</a> of a <a>table-root</a>,
as determined by the <a href="#dimensioning-the-row-column-grid">grid-dimensioning algorithm</a>.
Each row of the grid might correspond to a <a>table-row</a>, and each column to a <a>table-column</a>.
<dt><dfn noexport id="slot">slot</dfn> of the table grid
<dd>
A <a>slot</a> <code>(r,c)</code> is an available space created
by the intersection of a row <code>r</code> and a column <code>c</code> in the <a>table grid</a>.
Each slot of the table grid is covered by at least one <a>table-cell</a> (<a href="#missing-cells-fixup">some of them anonymous</a>), and at most two.
Each table-cell of a table-root covers at least one slot.
Table-cells which cover more than one slot do so densely,
meaning the set of slots they cover can always be described as a set of four strictly-positive integers <code>(rowStart, colStart, rowSpan, colSpan)</code>
such that a slot <code>(r,c)</code> is covered by the table-cell
if and only if <code>r</code> lies in the interval between <code>rowStart</code> (included) and <code>rowStart+rowSpan</code> (excluded),
and <code>c</code> lies in the interval between <code>colStart</code> (included) and <code>colStart+colSpan</code> (excluded);
Such table-cell is said to <dfn>originate</dfn> from row <code>rowStart</code> and column <code>colStart</code>.
Also:
<ul><li>A table-cell is said to originate a table-row <i>(resp. table-column)</i> if it originates its corresponding row <i>(resp. column)</i>
<li>A table-cell is said to originate a table-row-group <i>(resp. table-column-group)</i> if the group contains the cell's originating row <i>(resp. column)</i>
</ul>
Such table-cell is said to <dfn>span</dfn> all rows <code>r</code> and columns <code>c</code> matching the above condition.
Also:
<ul><li>A table-cell is said to span a table-row <i>(resp. table-column)</i> if it spans its corresponding row <i>(resp. column)</i>
<li>A table-row <i>(resp. table-column)</i> corresponding to a row <i>(resp. column)</i> is said to span this row <i>(resp. column)</i>
<li>A table-row <i>(resp. table-column)</i> is said to span all columns of the grid <i>(resp. row)</i>
<li>A table-row-group <i>(resp. table-column)</i> containing a row <i>(resp. column)</i> is said to span the row <i>(resp. column)</i>
<li>A table-row-group <i>(resp. table-column)</i> is said to span all columns of the grid <i>(resp. row)</i>
</ul>
</dl>
<!--
████████ ████ ██ ██ ██ ██ ████████
██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ███ ██ ██ ████████
██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██
██ ████ ██ ██ ███████ ██
-->
<h3 id="fixup">Fixup</h3>
Document languages other than HTML may not contain all the elements in the CSS 2.1 table model.
In these cases, the "missing" elements must be assumed in order for the table model to work.
Any <a>table-internal</a> element will automatically generate necessary anonymous table objects around itself, if necessary.
Any descendant of a <a>table-root</a> that is not table-internal
must have a set of ancestors in the table consisting of
at least three nested objects corresponding to
a <a>table</a>/<a>inline-table</a>,
a <a>table-row</a>, and
a <a>table-cell</a>.
Missing boxes cause the generation of <a href="#fixup-boxes">anonymous boxes</a> according to the following rules:
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="fixup-algorithm">Fixup Algorithm</h4>
For the purposes of these rules, out-of-flow elements are represented as inline elements of zero width and height.
Their containing blocks are chosen accordingly.
The following steps are performed in three stages:
<ol>
<li><b>Remove irrelevant boxes:</b><br/>
The following boxes are discarded as if they were <code>display:none</code>:
<ol>
<li>Children of a <a>table-column</a>.
<li>Children of a <a>table-column-group</a> which are not a <a>table-column</a>.
<li>Anonymous inline boxes which contain only white space and
are between two immediate siblings each of which is a <a>table-non-root</a> box.
<li>Anonymous inline boxes which meet all of the following criteria:
<ul>
<li>they contain only white space
<li>they are the first and/or last child of a <a>tabular container</a>
<li>whose immediate sibling, if any, is a <a>table-non-root</a> box
</ul>
</ol>
</li>
<li><b>Generate missing child wrappers:</b>
<ol>
<li>An anonymous <a>table-row</a> box must be generated
around each sequence of consecutive children of a <a>table-root</a> box
which are not <a>proper table child</a> boxes.
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/2/">!!Testcase</a>
<li>An anonymous <a>table-row</a> box must be generated
around each sequence of consecutive children of a <a>table-row-group</a> box
which are not <a>table-row</a> boxes.
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/3/">!Testcase</a>
<li>An anonymous <a>table-cell</a> box must be generated
around each sequence of consecutive children of a <a>table-row</a> box
which are not <a>table-cell</a> boxes.
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/4/">!Testcase</a>
</ol>
</li>
<li><b>Generate missing parents:</b>
<ol>
<li>An anonymous <a>table-row</a> box must be generated
around each sequence of consecutive <a>table-cell</a> boxes
whose parent is not a <a>table-row</a>.
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/5/">Testcase</a>
<li>An anonymous <a>table</a> or <a>inline-table</a> box must be generated
around each sequence of consecutive <a>proper table child</a> boxes
which are misparented.
If the box's parent is an inline, run-in, or ruby box (or any box that would perform inlinification of its children),
then an <a>inline-table</a> box must be generated;
otherwise it must be a <a>table</a> box.
<ul>
<li>A <a>table-row</a> is misparented
if its parent is neither a <a>table-row-group</a> nor a <a>table-root</a> box.
<li>A <a>table-column</a> box is misparented
if its parent is neither a <a>table-column-group</a> box nor a <a>table-root</a> box.
<li>A <a>table-row-group</a>, <a>table-column-group</a>, or <a>table-caption</a> box is misparented
if its parent is not a <a>table-root</a> box.
</ul>
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/7/">Testcase</a>
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/8/">Testcase</a>
<a class="hint" href="https://jsfiddle.net/hj2w7wwa/9/">!Testcase</a>
<li>An anonymous <a>table-wrapper</a> box must be generated around each <a>table-root</a>.
Its display type is <code>inline-block</code> for <a>inline-table</a> boxes and block for <a>table</a> boxes.
The table wrapper box establishes a block formatting context.
The table-root box (not the table-wrapper box) is used when doing baseline vertical alignment for an <a>inline-table</a>.
The width of the table-wrapper box is the border-edge width of the table grid box inside it.
Percentages which would depend on the 'width' and 'height' on the table-wrapper box's size are relative to the table-wrapper box's containing block instead, not the table-wrapper box itself.
</ol>
</li>
</ol>
<div class="note">
Please note that some layout modes such as flexbox and grid <a href="http://www.w3.org/TR/css-display-3/#blockify">override the display type</a> of their children.
These transformations happen before the table fixup.
</div>
<div class="note">
Please note that the 'float' and 'position' properties sometimes <a href="http://www.w3.org/TR/CSS22/visuren.html#dis-pos-flo">affect the computed value</a> of 'display'.
When those properties are used on what should have been table internal boxes, they switch to <code>block</code> instead.
This transformation happen before the table fixup.
</div>
<div class="note">
We have modified the text of this section from CSS 2.2 to make it easier to read.
If you find any mistakes due to these changes please file an issue
</div>
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="fixup-boxes">Characteristics of fixup boxes</h4>
Beside their display type, the anonymous boxes created for fixup purposes
do not receive any specific or default styling,
except where otherwise mentioned by this specification.
<div class="note">
This means in particular that
their computed background is “transparent”,
their computed padding is “0px”,
their computed border-style is “none”.
It is also worth reminding that an <a>anonymous box</a> inherits property values through the box tree.
</div>
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="fixup-examples">Examples</h4>
<div class="example">
<xmp class="lang-markup">
<div class="row">
<div class="cell">George</div>
<div class="cell">4287</div>
<div class="cell">1998</div>
</div>
</xmp>
Here is the associated styles:
<pre class="lang-css">
.row { display: table-row }
.cell { display: table-cell }
</pre>
After fixup, this will produce layout boxes as though this was the initial HTML:
<xmp class="lang-markup">
<table>
<tr>
<td>George</td>
<td>4287</td>
<td>1998</td>
</tr>
</table>
</xmp>
</div>
<div class="example">
In this example, three <a>table-cell</a> anonymous boxes are assumed to contain the text in the rows. The text inside
of the divs with a <code>display: table-row</code> are encapsulated in anonymous inline boxes, as explained in
<a href="https://www.w3.org/TR/CSS21/visuren.html#anonymous" target="_blank">visual formatting model</a>:
<xmp class="lang-markup">
<div class="inline-table">
<div class="row">This is the top row.</div>
<div class="row">This is the middle row.</div>
<div class="row">This is the bottom row.</div>
</div>
</xmp>
<pre class="lang-css">
.inline-table { display: inline-table; }
.row { display: table-row; }
</pre>
This will produce layout boxes as though this was the initial HTML:
<xmp class="lang-markup">
<table>
<tr>
<td>This is the top row.</td>
</tr>
<tr>
<td>This is the middle row.</td>
</tr>
<tr>
<td>This is the bottom row.</td>
</tr>
</table>
</xmp>
</div>
<!--
██ ███ ██ ██ ███████ ██ ██ ████████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ████ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██
██ █████████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██
████████ ██ ██ ██ ███████ ███████ ██
-->
<h2 id="layout">Layout</h2>
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="layout-principles">Core layout principles</h3>
Unlike other block-level boxes, tables do not fill their containing block by default.
When their 'width' computes to <code>auto</code>, they behave as if they had <code>fit-content</code> specified instead.
This is different from most block-level boxes, which behave as if they had <code>stretch</code> instead.
The <dfn id="min-content-width-of-a-table">min-content width of a table</dfn> is
the width required to fit all of its columns min-content widths and its undistributable spaces.
The <dfn id="max-content-width-of-a-table">max-content width of a table</dfn> is
the width required to fit all of its columns max-content widths and its undistributable spaces.
If the width assigned to a table is larger than its <a href="#min-content-width-of-a-table">min-content width</a>,
the <a href="#width-distribution">Available Width Distribution</a> algorithm
will adjust column widths in consequence.
This section overrides the general-purpose rules that apply to calculating widths described in other specifications.
In particular, if the margins of a table are set to <code>0</code> and the width to <code>auto</code>,
the table will not automatically size to fill its containing block.
However, once the used value of <code>width</code> for the table is found (using the algorithms given below)
then the other parts of those rules do apply.
Therefore, a table can be centered using left and right <code>auto</code> margins, for instance.
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="table-layout-algorithm">Table layout algorithm</h3>
To layout a table, user agents must apply the following actions:
<ol>
<li><b>Determine the number of rows/columns the table requires.</b><br/>
This is done by executing the steps described in [[#dimensioning-the-row-column-grid]].
<li><b>[A] If the row/column grid has at least one <a>slot</a>:</b>
<ol>
<li><b>Ensure each cell <a>slot</a> is occupied by at least one cell.</b><br/>
This is done by executing the steps described in [[#missing-cells-fixup]].
<li><b>Compute the minimum width of each column.</b><br/>
This is done by executing the steps described in [[#content-measure]].
<li><b>Compute the width of the table.</b><br/>
This is done by executing the steps described in [[#computing-the-table-width]].
<li><b>Distribute the width of the table among columns.</b><br/>
This is done by executing the steps described in [[#width-distribution-algorithm]].
<li><b>Compute the height of the table.</b><br/>
This is done by executing the steps described in [[#computing-the-table-height]].
<li><b>Distribute the height of the table among rows.</b><br/>
This is done by executing the steps described in [[#height-distribution-algorithm]].
</ol>
<b>[B] Else, an <dfn id="empty-table">empty table</dfn> is laid out:</b>
<ol>
<li><b>Compute the width of the table.</b><br/>
This is done by returning the largest value of <a href="#capmin">CAPMIN</a>
and the computed width of the table grid box (including borders and paddings)
if it is definite (use zero otherwise).
<li><b>Compute the height of the table.</b><br/>
This is done by returning the sum of all table-caption heights
(their width being set to the table width,
with margins taken into consideration appropriately)
and the computed height of the table grid box (including borders and paddings)
if it is definite (use zero otherwise).
</ol>
<li><b>Assign to each table-caption and table-cell their position and size.</b><br/>
This is done by running the steps of [[#bounding-box-assignment]].
</ol>
<figure>
<p class="note">
The following schema describes the algorithm in a different way,
to make it easier to understand.
</p>
<img alt="[see-caption-below]" src="images/CSS-Tables-Layout-Merged.svg" style="width: 100%">
<figcaption>Overview of the table layout algorithm. Not normative.</figcaption>
</figure>
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="dimensioning-the-row-column-grid">Dimensioning the row/column grid</h3>
Like mentioned in the <a href="#table-structure">Table structure</a> section,
how many rows and columns a table has
can be determined from the table structure.
Both dimensioning the row/column <a>grid</a> and assigning table-cells their <nobr><a>slot</a>(s)</nobr> in that grid
do require running the HTML Algorithms for tables.
<h4 id="dimensioning-the-row-column-grid--step1">HTML Algorithm</h4>
<p class="note">
CSS Boxes that do not originate from an HTML table element equivalent to their display type
need to be converted to their HTML equivalent before we can apply this algorithm, see below.
There is no way to specify the <a>span</a> of a cell in css only in this level of the spec,
the use of an HTML td element is required to do so.
Apply the <a href="https://www.w3.org/TR/html5/tabular-data.html#forming-a-table">HTML5 Table Formatting algorithm</a>,
where boxes act like <a href="#display-types">the HTML element equivalent to their display type</a>,
and use the attributes of their originating element if and only if it is an HTML element of the same type
(otherwise, they act like if they didn't have any attribute).
<div class="example">
<xmp class="lang-markup">
<ul class="table">
<li><b>One</b><i>1</i></li>
<li><b>Two</b><i>2</i></li>
<li><b>Three</b><i>3</i></li>
</ul>
<style>
ul.table { display: table; }
ul.table > li { display: table-row; }
ul.table > li > * { display: table-cell; }
</style>
</xmp>
produces the same row/column grid as
<xmp class="lang-markup">
<table><tbody>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody></table>
</xmp>
</div>
<div class="example">
<pre class="lang-markup" style="margin-bottom:0;padding-bottom:0;">
<!-- built using dom api, as this would be fixed by the html parser -->
</pre>
<xmp class="lang-markup" style="margin-top:0;padding-top:0;">
<grid style="display: table">
<row style="display: table-row">
<th rowspan="2">1</th>
<colgroup style="display: table-cell" span="2" colspan="2">2</colgroup>
</row>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</grid>
</xmp>
produces the same row/column grid as
<xmp class="lang-markup">
<table>
<tr>
<th rowspan="2">1</th>
<td>2</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</table>
</xmp>
Note how the second cell of the first row doesn't have ```colspan=2``` applied, because its originating element is not an HTML TD element.
<a class="hint" href="https://jsfiddle.net/eqrwaLyc/">Testcase</a>.
<a class="hint" href="https://jsfiddle.net/eqrwaLyc/1/">!!Testcase</a>.
<a class="hint" href="https://jsfiddle.net/sckxeLmh/2/">!Test case</a>.
<a class="hint" href="https://jsfiddle.net/sckxeLmh/4/">!!Test case</a>.
<a class="hint" href="https://jsfiddle.net/sckxeLmh/5/">!!Test case</a>.
</div>
<h4 id="dimensioning-the-row-column-grid--step2">Track merging</h4>
<p class="note">
The HTML Table Formatting algorithm sometimes generates more tracks than necessary to layout the table properly.
Those tracks have historically been ignored by user agents,
so the next step just gets rid of them entirely to avoid dealing with them as exceptions later in the spec.
We have tried to maintain the functionality with this change, but if you happen to find any issues
due to this change please file an issue.
Modify iteratively the obtained grid by merging consecutive tracks as follows:
As long as there exists an <a>eligible track</a> in the obtained row/column grid such that
there is no table-column/table-row box defining the said track explicitly, and
both the said track and the previous one are spanned by the exact same set of cells,
those two tracks must be merged into one single track for the purpose of computing the layout of the table.
Reduce the <a>span</a> of the cells that spanned the deleted track by one to compensate,
and shift similarly the tracks from which cells <a>originate</a> when needed.
<span class="hint">(see <a href="#spanning-ghost-rows">spanning-ghost-rows test cases</a>)</span>
For tables <a>in auto mode</a>, every track is an <dfn>eligible track</dfn> for the purpose of the track-merging algorithm.
For tables <a>in fixed mode</a>, only rows are eligible to be merged that way; which means that every column is preserved.
Finally, assign to the <a>table-root</a> grid its correct number of rows and columns (from its mapped element),
and to each <a>table-cell</a> its accurate <a href="#slot">rowStart/colStart/rowSpan/colSpan</a> (from its mapped element).
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="missing-cells-fixup">Missing cells fixup</h3>
<p class=note>
The following section clarifies and extends the CSS 2.1 statement saying that
missing cells are rendered as if an anonymous table-cell box occupied their position in the grid
(a "missing cell" is a slot in the row/column grid that is not covered yet by any table-cell box).
Once the amount of columns in a table is known, any table-row box must be modified such that
it owns enough cells to fill all the columns of the table, when taking <a>spans</a> into account.
New table-cell <a href="#fixup-boxes">anonymous boxes</a> must be appended to its rows content until this condition is met.
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="layout-modes">Table layout modes</h3>
This section covers the flags which modify the way tables are being laid out.
There are three major flags for table layout: 'table-layout', 'border-collapse', and 'caption-side'.
The 'border-collapse' flag has an optional 'border-spacing' parameter.
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="table-layout-property">The Table-Layout property</h4>
<pre class='propdef'>
Name: table-layout
Value: auto | fixed
Initial: auto
Applies to: <a>table grid boxes</a>
Inherited: no
Computed value: specified keyword
Animation type: discrete
</pre>
A table-root is said to be laid out <dfn>in fixed mode</dfn>
whenever the computed value of the 'table-layout' property is equal to <code>fixed</code>,
and the specified width of the table root is either
a <code><length-percentage></code>,
<code>min-content</code> or
<code>fit-content</code>.
When the specified width is not one of those values,
or if the computed value of the 'table-layout' property is <code>auto</code>,
then the table-root is said to be laid out <dfn>in auto mode</dfn>.
When a table-root is laid out <a>in fixed mode</a>,
the content of its table-cells is ignored for the purpose of width computation,
the aggregation algorithm for column sizing considers only table-cells belonging to the first row track,
such that layout only depends on the values explicitly specified for the table-columns or cells of the first row of the table;
columns with indefinite widths are attributed their fair share of the remaining space
after the columns with a definite width have been considered, or 0px if there is no remaining space
(see [[#computing-column-measures]]).
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="border-collapse-property">The Border-Collapse property</h4>
<pre class='propdef'>
Name: border-collapse
Value: separate | collapse
Initial: separate
Applies To: <a>table grid boxes</a>
Inherited: yes
Computed value: specified keyword
Animation type: discrete
</pre>
When the 'border-collapse' property has <code>collapse</code> as its value,
the borders of adjacent cells are merged together such that each cell draws only half of the shared border.
As a result, some other properties like 'border-spacing' will not applied in this case (see [[#collapsed-style-overrides]]),
(see [[#border-collapsing]]).
A <a>table-root</a> is said to be laid out <dfn>in collapsed-borders mode</dfn> in this case.
Otherwise, the <a>table-root</a> is said to be laid out <dfn>in separated-borders mode</dfn>.
<!--——————————————————————————————————————————————————————————————————————————-->
<h5 id="border-spacing-property">The Border-Spacing property</h5>
<pre class='propdef'>
Name: border-spacing
Value: <<length>>{1,2}
Initial: 0px 0px
Inherited: yes
Applies To: <a>table grid boxes</a> when 'border-collapse' is ''border-collapse/separate''
Computed Value: two absolute lengths
Animation type: by computed value
</pre>
The lengths specify the distance that separates adjoining cell borders <a>in separated-borders mode</a>,
and must not be strictly negative.
If one length is specified, it gives both the horizontal and vertical spacing.
If two are specified, the first gives the horizontal spacing and the second the vertical spacing.
See [[#computing-undistributable-space]] for details on how this affects the table layout.
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="caption-side-property">The Caption-Side property</h4>
<pre class='propdef'>
Name: caption-side
Value: top | bottom
Initial: top
Applies to: <a>table-caption</a> boxes
Inherited: yes
Computed value: specified keyword
Animation type: discrete
</pre>
This property specifies the position of the caption box with respect to the table grid box.
Values have the following meanings:
<dl>
<dt><dfn id="caption-side-top">top</dfn>
<dd>
Positions the caption box above the table grid box.
<dt><dfn id="caption-side-bottom">bottom</dfn>
<dd>
Positions the caption box below the table grid box.
</dl>
<div class="note">
CSS2 described a different width and horizontal alignment behavior.
That behavior was supposed to be introduced in CSS3
using the values <code>top-outside</code> and <code>bottom-outside</code>.
<a href="http://fantasai.inkedblade.net/style/discuss/captions/">#REF</a>
</div>
<div class="note">
Gecko also supports the "left" and "right" values, but currently this specification
is not attempting to define their implementation of said values.
</div>
<div class="note">
Gecko has a bug when dealing with multiple captions.
<a class="hint" href="http://codepen.io/FremyCompany/pen/WrJxwP">!Testcase</a>
</div>
<div class="example">
To align caption content horizontally within the caption box, use the 'text-align' property.
In this example, the 'caption-side' property places captions below tables.
The caption will be as wide as the parent of the table, and caption text will be left-justified.
<pre>
caption {
caption-side: bottom;
width: auto;
text-align: left
}
</pre>
</div>
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="style-overrides">Style overrides</h3>
Some css properties behave differently inside css tables.
The following sections list the exceptions and their effects.
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="global-style-overrides">Overrides applying in all modes</h4>
The following rules apply to all tables, irrespective of the layout mode in use.
<ul>
<li>The computed values of properties 'position', 'float', 'margin'-*, 'top', 'right', 'bottom', and 'left' on the table
are used on the table-wrapper box and not the table grid box;
the same holds true for the properties whose use could force the used value of 'transform-style' to <code>flat</code></a> (see [[css-transforms-2#grouping-property-values|list]]) and their shorthands/longhands relatives:
this list currently includes 'overflow', 'opacity', 'filter', 'clip', 'clip-path', 'isolation', 'mask'-*, 'mix-blend-mode', 'transform'-* and 'perspective'.
<br>
Where the specified values are not applied on the table grid and/or wrapper boxes,
the unset values are used instead for that box (inherit or initial, depending on the property).
<li>The 'overflow' property on the <a>table-root</a> and <a>table-wrapper</a> box, when its value is not either <code>visible</code>, <code>clip</code> or <code>hidden</code>,
is ignored and treated as if its value was <code>visible</code>.
<li>All css properties of <a>table-column</a> and <a>table-column-group</a> boxes are ignored,
except when explicitly specified by this specification.
<li>The 'margin', 'padding', 'overflow' and 'z-index' of <a>table-track</a> and <a>table-track-group</a> boxes are ignored.
<li>The 'margin' of <a>table-cell</a> boxes is ignored (as if it was set to 0px).
<li>The 'background' of <a>table-cell</a> boxes
are painted using a special background painting algorithm described in [[#drawing-cell-backgrounds]].
</ul>
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="collapsed-style-overrides">Overrides applying in collapsed-borders mode</h4>
When a table is laid out <a>in collapsed-borders mode</a>, the following rules apply:
<ul>
<li>The 'padding' of the <a>table-root</a> is ignored (as if it was set to 0px).
<li>The 'border-spacing' of the <a>table-root</a> is ignored (as if it was set to 0px).
<li>The 'border-radius' of both <a>table-root</a> and <a>table-non-root</a> boxes
is ignored (as if it was set to 0px).
<li>The values used for the layout and rendering of the borders of the <a>table-root</a>
and the <a>table-cell</a> boxes it owns are
determined using a special conflict resolution algorithm described in [[#border-collapsing]].
</ul>
<!--——————————————————————————————————————————————————————————————————————————-->
<h3 id="border-collapsing">Border-collapsing</h3>
<div class="note">
This entire section is a proposal to make the rendering of collapsed borders sane.
As implementations diverge very visibly, it is expected to require more discussion than some other parts.
Since browsers handle this so differently, convergence cannot happen without reimplementation.
A major concern for this proposal was to support as many cases as possible, and yet
keep the effort required for a new implementation of tables as low as possible.
<b>Background:</b>
CSS+HTML allow unprecedented combinations of border modes for table junctions,
and it makes it difficult to support all cases properly;
in fact some combinations are not <a href="https://en.wikipedia.org/wiki/Well-posed_problem">well-posed problems</a>,
so no rendering algorithm could be optimal.
Because they grew from something simple (HTML) to something very complex (HTML+CSS),
the current table rendering models (backgrounds and borders) used by web browsers are insane
(in the sense they are buggy, not interoperable and not CSSish at all).
Many usual CSS assumptions are broken, and renderings diverge widely.
This proposal aims at fixing this situation.
</div>
ISSUE(604): border-collapsing breaking change from 2.1
<!--——————————————————————————————————————————————————————————————————————————-->
<h4 id="conflict-resolution-for-collapsed-borders">Conflict Resolution for Collapsed Borders</h4>
When they are laid out <a>in collapsed-borders mode</a>,
<a>table-root</a> and <a>table-cell</a> boxes sharing a border attempt to unify their borders
so that they render using the same style, width, and color (whenever this is possible).
This is accomplished by running the following algorithm.
<!--——————————————————————————————————————————————————————————————————————————-->
<h5 id="border-conflict-resolution-algorithm">Conflict Resolution Algorithm for Collapsed Borders</h5>
<div class="note">