-
Notifications
You must be signed in to change notification settings - Fork 790
Expand file tree
/
Copy pathOverview.bs
More file actions
3193 lines (2688 loc) · 135 KB
/
Overview.bs
File metadata and controls
3193 lines (2688 loc) · 135 KB
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
<h1>CSS Table Module Level 3</h1>
<pre class='metadata'>
Shortname: css-tables-3
Level: 3
Status: ED
Work Status: Exploring
Group: csswg
ED: https://drafts.csswg.org/css-tables-3/
TR: https://www.w3.org/TR
4B6C
/CSS2/tables.html
Editor: Francois Remy, Microsoft
Editor: Greg Whitworth, Microsoft
Former editor: Bert Bos, W3C
Former editor: David Baron, Mozilla
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>
<pre class=link-defaults>
spec:css21; type:property; text:min-width
spec:css21; type:property; text:max-width
</pre>
<!--------------------------------------------------------------------------------->
<h2 id="intro">Introduction</h2>
<p><em>This section is not normative</em></p>
<p>
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 items property
(ex: the temperatures measured over the past year).
<p>
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).
<p>
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.
<p>
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.
<p>
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 Grids.
<!--------------------------------------------------------------------------------->
<h2 id="content-model">Content Model</h2>
<!--------------------------------------------------------------------------------->
<h3 id="table-structure">Table Structure</h3>
<p>
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.
<p>
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).
<p>
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 [[#spanning]] and [[#dimensioning-the-row-column-grid]])</span>.
<p>
To summarize, an instance of the table model consists of:
<ul class="compact">
<li>Its <a href="#table-root-element">table-root element</a> containing:
<ul>
<li>Zero, one or more <a href="#table-row">table rows</a>, optionally in <a href="#table-row-grouping-element">row groups</a>,
<ul><li>Each of them contaning 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: a <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 src="images/table-structure.png" width=493 />
<figcaption>Two representations of the structure of a table (tree vs layout)</figcaption>
</figure>
<p>
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.
<p>
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 block-level table:
it is a rectangular block that participates in a block formatting context.
<dt><dfn>inline-table</dfn> (equivalent to HTML: <table>)
<dd>Specifies that an element defines an inline-level table:
it is a rectangular block that participates in an inline formatting context).
<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.
<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 contains multiple elements with <code>display: table-header-group</code>,
only the first is rendered 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 contains multiple elements with <code>display: table-footer-group</code>,
only the first is rendered 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>
<h4 id="terminology">Terminology</h2>
<p>
In addition to the table structure display types,
the following wording is also being used in this spec:
<dl>
<dt><dfn id="table-root-element">table-root</dfn> box or element
<dd>
A <a>table</a> or <a>inline-table</a> box.
<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-row-grouping-element">table-row-grouping</dfn> box or element
<dd>
A
<a>table-row-group</a>,
<a>table-header-group</a>, or
<a>table-footer-group</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-grouping-element">table-track-grouping</dfn> box or element
<dd>
A
<a>table-row-grouping</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-grouping</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-grouping</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-grouping</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 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.
</dl>
<dt><dfn id="table-slot">slot</dfn>
<dd>
The <a>slot</a> is an available space created by the intersection of and inline and block
<a>table-track</a>.
<!--------------------------------------------------------------------------------->
<h3 id="fixup">Fixup</h3>
<p>
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.
<p>
Any <a>table-internal</a> element will automatically generate necessary anonymous table objects around itself, if necessary.
Any non-table descendant of a <a>table-root</a> must have a ancestors consisting of
at least three nested objects corresponding to
a <a>table</a>/<a>inline-table</a> element,
a <a>table-row</a> element, and
a <a>table-cell</a> element.
Missing elements cause the generation of anonymous boxes according to the following rules:
<!--------------------------------------------------------------------------------->
<h4 id="fixupAlgo">Fixup Algorithm</h4>
<p>
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.
<p>
The following steps are performed in three stages:
<ol>
<li><b>Remove irrelevant boxes:</b>
<ol>
<li>Children of a <a>table-column</a> are treated as if they had <code>display: none</code>.
<li>Children of a <a>table-column-group</a> which are not a <a>table-column</a> are treated
as if they had <code>display: none</code>.
<li>Anonymous inline boxes which contains only white space,
are the first or last child of a <a>tabular container</a>,
and whose immediately preceding or following sibling (if any) is a <a>table-non-root</a> element,
are treated as if they had <code>display: none</code>.
<li>Anonymous inline boxes which contains only white space and
are between two immediate siblings each of which is a <a>table-non-root</a> element,
are treated as if they had <code>display: none</code>.
</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-grouping</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> box
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> box
which are misparented.
If the box's parent is an inline box,
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-grouping</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-grouping</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>
</ol>
</li>
</ol>
<!--------------------------------------------------------------------------------->
<h4 id="fixup-examples">Examples</h4>
<div class="example">
<pre class="lang-markup">
<div class="row">
<div class="cell">George</div>
<div class="cell">4287</div>
<div class="cell">1998</div>
</div>
</pre>
<p>Here is the associated styles:</p>
<pre class="lang-css">
.row { display: table-row }
.cell { display: table-cell }
</pre>
<p>After fixup, this will produce layout boxes as though this was the initial HTML:</p>
<pre class="lang-markup">
<table>
<tr>
<td>George</td>
<td>4287</td>
<td>1998</td>
</tr>
</table>
</pre>
</div>
<div class="example">
<p>In this example, three <a>table-cell</a> elements 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>:</p>
<pre 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>
</pre>
<pre class="lang-css">
.inline-table { display: inline-table; }
.row { display: table-row; }
</pre>
<p>This will produce layout boxes as though this was the initial HTML:</p>
<pre 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>
</pre>
</div>
<!--------------------------------------------------------------------------------->
<h3 id="mapping">Mapping between CSS & HTML attributes</h3>
<p>
The default style sheet for HTML4 illustrates how its model maps to css properties and values:
<div class="note">
Some extensions to CSS have been used where contraints not mappable to current CSS apply
</div>
<pre class="lang-css">
table { display: table }
thead { display: table-header-group }
tbody { display: table-row-group }
tfoot { display: table-footer-group }
tr { display: table-row }
td, th { display: table-cell }
colgroup { display: table-column-group }
col { display: table-column }
caption { display: table-caption }
table, thead, tbody, tfoot, tr, td, th, colgroup, col, caption { box-sizing: border-box; }
<!--
Non-border built-ins
-->
table {
box-sizing: border-box;
border-spacing: 2px;
border-collapse: separate;
text-indent: initial;
}
thead, tbody, tfoot, table > tr { vertical-align: middle; }
tr, td, th { vertical-align: inherit; }
td, th { padding: 1px; }
th { font-weight: bold; }
table, td, th { border-color: gray; }
thead, tbody, tfoot, tr { border-color: inherit; }
<!--
Border built-ins
-->
<!--
FRAME (part 1/2)
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_table_frame
-->
table[frame=box], table[frame=border], table[frame=hsides], table[frame=above], table[frame=below], table[frame=vsides], table[frame=lhs], table[frame=rhs] {
border: 1px solid inset;
}
<!--
RULES (part 1/3)
http://codepen.io/FremyCompany/pen/GopJMp
-->
table:matches([rules=all], [rules=rows], [rules=cols], [rules=groups], [rules=none]) {
border-collapse: collapse;
border-style: hidden;
}
table:matches([rules=all], [rules=rows], [rules=cols], [rules=groups], [rules=none]),
table:matches([rules=all], [rules=rows], [rules=cols], [rules=groups], [rules=none]) > :matches(thead,tbody,tfoot) > tr > :matches(th,td) {
border-color: black;
}
<!--
BORDER
http://codepen.io/FremyCompany/pen/EPVjNp
-->
table[border=$border] /* if(parseInt($border) > 0) */ {
border: /*(parseInt($border) * 1px)*/ outset rgb(128, 128, 128);
}
table[border=$border] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) /* if(parseInt($border) > 0) */ {
border: 1px inset rgb(128, 128, 128);
}
<!--
RULES (part 2/3)
http://codepen.io/FremyCompany/pen/GopJMp
-->
table[rules=all] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) {
border: 1px solid grey;
}
table[rules=rows] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) {
border: 1px solid grey;
border-left: none;
border-right: none;
}
table[rules=cols] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) {
border: 1px solid grey;
border-top: none;
border-bottom: none;
}
table[rules=none] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) {
border: none;
}
<!--
RULES (part 3/3)
http://codepen.io/FremyCompany/pen/jWbPXY
https://jsfiddle.net/ewv08n0r/
-->
table[rules=groups] > :matches(thead,tbody,tfoot) {
border-top-width: 1px; border-top-style: solid;
border-bottom-width: 1px; border-bottom-style: solid;
}
table[rules=groups] > colgroup {
border-left-width: 1px; border-left-style: solid;
border-right-width: 1px; border-right-style: solid;
}
<!--
FRAME (part 2/2)
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_table_frame
-->
table[frame=box], table[frame=border], table[frame=hsides], table[frame=above], table[frame=below], table[frame=vsides], table[frame=lhs], table[frame=rhs] {
border-style: inset;
}
table[frame=below], table[frame=vsides], table[frame=lhs], table[frame=rhs] {
border-top-style: hidden;
}
table[frame=above], table[frame=vsides], table[frame=lhs], table[frame=rhs] {
border-bottom-style: hidden;
}
table[frame=hsides], table[frame=above], table[frame=below], table[frame=rhs] {
border-left-style: hidden;
}
table[frame=hsides], table[frame=above], table[frame=below], table[frame=rhs] {
border-right-style: hidden;
}
<!--
Others:
-->
table[cellpadding=$x] > :matches(thead,tbody,tfoot) > tr > :matches(th,td) /* if(parseInt($x)>0) */ {
padding: /*(parseInt($x) * 1px)*/;
}
table[cellspacing=$x] /* if(parseInt($x)>0) */ {
border-spacing: /*(parseInt($x) * 1px)*/;
}
table[width=$w] /* if(parseInt($w) > 0) */ {
width: /*(parseInt($w) * 1px)*/;
}
table[width=$w] /* if($w matches /(+|-|)([0-9]+([.][0-9]+|)|([.][0-9]+))[%]/) */ {
width: /*(parseInt($w) * 1px)*/;
}
table[height=$h] /* if(parseInt($h) > 0) {
height: /*(parseInt($h) * 1px)*/;
}
table[height=$h] /* if($h matches /(+|-|)([0-9]+([.][0-9]+|)|([.][0-9]+))[%]/) */ {
height: /*(parseInt($h) * 1px)*/;
}
table[bgcolor=$color] {
background-color: /*parseHTMLColor($color)*/;
}
table[align=left] {
float: left;
}
table[align=right] {
float: right;
}
table[align=center] {
margin-left: auto;
margin-right: auto;
}
<!--
NON-TABLE ATTRIBUTES:
-->
caption[align=bottom i] { caption-side: bottom; }
:matches(thead,tbody,tfoot,tr,td,th)[valign=top i] {
vertical-align: top;
}
:matches(thead,tbody,tfoot,tr,td,th)[valign=middle i] {
vertical-align: middle;
}
:matches(thead,tbody,tfoot,tr,td,th)[valign=bottom i] {
vertical-align: bottom;
}
:matches(thead,tbody,tfoot,tr,td,th)[valign=bottom i] {
vertical-align: baseline;
}
:matches(thead,tbody,tfoot,tr,td,th)[align=absmiddle i] {
text-align: center;
}
:matches(colgroup,col,thead,tbody,tfoot,tr,td,th)[hidden] {
visibility: collapse;
}
:matches(td,th)[nowrap] { white-space: nowrap; }
:matches(td,th)[nowrap][width=$w] /* if(quirksMode && parseInt($w) > 0) */ {
white-space: normal;
}
</pre>
<div class="issue">
We should merge/review the WHATWG spec on
<a href="https://html.spec.whatwg.org/#tables-2">HTML to CSS mapping of tables</a>.
They cover a few attributes I didnt't test including nowrap (which has interesting issues).
They also include <a href="https://jsfiddle.net/8t78exf1/">things which are not true</a> in most browsers.
Investigations are therefore required for each and any merge being made!
</div>
<!--------------------------------------------------------------------------------->
<h3 id="spanning">Spanning</h3>
<p style="font-size: italic">
This section will explain what is spanning
and how it will affect algorithms later in this spec.
<p class="issue">
We should define how spanning works.
<!--------------------------------------------------------------------------------->
<h2 id="layout">Layout</h2>
<!--------------------------------------------------------------------------------->
<h3 id="layout-principles">Core layout principles</h3>
<p>
Unlike other block elements, tables do not fill their containing block by default.
By default, the width of a table depends on the width required to fit its columns preferred width.
The minimum width of a table is the width required to fit all its columns min-width and its undistributable spaces.
<p>
If the width assigned to a table is larger than its minimum width,
the <a href="#width-distribution">Available Width Distribution</a> algorithm
will adjust column widths in consequence.
<p>
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>
<p>To layout a table, user agents must apply the following actions:
<ol>
<li><b>If the table has at least one caption, compute their minimum width.</b><br/>
This is done by computing the caption's min-content width (including margins, borders and paddings)
under the assumption their parent has a zero width and overflow:visible.
The largest such width will be known as <a href="#capmin">CAPMIN</a>.
<li><b>Determine the amount 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 minimun width of each row/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, if the table is empty:</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 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 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="advisement">
The following schema describes the algorithm in a different way,
to make it easier to understand.
</p>
<img src="images/CSS-Tables-Layout-Merged.svg" style="width: 100%" />
<figcaption>Overview of the table layout algorithm. Not normative.</figcaption>
</figure>
<div class="issue">
<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>
<!--------------------------------------------------------------------------------->
<h3 id="dimensioning-the-row-column-grid">Dimensioning the row/column grid</h3>
<p style="font-size: italic">
This section explains how to decide how many rows and columns a table has.
<p>
Like mentioned in the <a href="#table-structure">Table structure</a> section,
the amount of rows and columns defined in a table can be determined from the
table structure.
<div class="note">
In the following algorithm, "Map $box to a HTML element if needed" means:
<li>Let $elm be the HTML equivalent tag name of the display type of $box,
as defined in <a href="#display-types">the display types list</a>:
<ul class="compact" style="margin:0 !important">
<li>If $box originates from an HTML $elm element,
<ul><li>Clone that element and its attributes (but not its descendants) and return it;</ul>
<li>Else,
<ul><li>Create a new HTML $elm element with no attribute and return it</ul>
</ul>
In both cases, save the relationship between the newly created element and $box.
</div>
<p>
To find out how many columns and rows the row/column grid of a table contains,
and where each cell element takes place in that grid, the user agent must
convert the css table to its equivalent html markup, using the following algorithm:
<ol>
<li>Map the <a>table-root</a> to a HTML element if needed
<li>While there is one, and in DOM order,
map to a HTML element if needed
every child box of the <a>table-root</a>,
and append those to the <table> element.
<li>While there is one, and in DOM order,
map to a HTML element if needed
every non-mapped <a>table-internal</a> box of the <a>table-root</a>
that is also a child of any already mapped box
and append those to the element that was mapped to their parent box.
</ol>
<a class="hint" href="https://jsfiddle.net/eqrwaLyc/">Testcase</a>.
<a class="hint" href="https://jsfiddle.net/eqrwaLyc/1/">!!Testcase</a>.
<p>
Once this is done, apply the <a href="https://www.w3.org/TR/html5/tabular-data.html#forming-a-table">HTML5 Table Formatting algorithm</a>.
<p>
Modify the obtained row/column grid such that
consecutive tracks spanned by the same set of cells
are merged into one single track
for the purpose of computing the layout of the table
if except the first of such sequence of tracks
there is no table-column/table-row element defining them explicitely;
if 'table-layout' computes to 'fixed' on the table-root,
columns are however never merged together.
Change the spanning of the cells contained in those tracks
accordingly so that no difference is shown.
<span class="hint">(see <a href="#spanning-ghost-rows">spanning-ghost-rows test cases</a>)</span>
<p>
Finally, assign to the <a>table-root</a> element its correct amount of rows and columns (from its mapped element),
and to each <a>table-cell</a> element its accurate table-row-start/table-column-start/table-row-span/table-column-span (from its mapped element).
<div class="issue">
The HTML specification mentions that in some cases, two cells may occupy the same row/column location.
We need to make sure this specification explains what happens in this case for layout/rendering.
</div>
<div class="example">
<pre class="lang-markup">
<ul class="table">
<li><label>One</label><input /></li>
<li><label>Two</label><input /></li>
<li><label>Three</label><input /></li>
</ul>
<style>
ul.table { display: table; }
ul.table > li { display: table-row; }
ul.table > li > * { display: table-cell; }
</style>
</pre>
produces the same row/column grid as
<pre 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>
</pre>
</div>
<!--------------------------------------------------------------------------------->
<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 cell in the row/column grid that is not occupied by an element or pseudo-element).
<p>
Once the amount of columns in a table is known, any table-row-group element must be modified such that
each of its rows contains enough cells to fill all the columns of the table, when taking spanning into account.
New table-cell pseudo-elements must be appended to its rows content until this condition is met.
<p>
Beside their display type, those pseudo-elements do not receive any specific or default styling,
except where otherwise mentioned by this specification
(meaning
their background is “transparent”,
their padding is “0px” and
their border is “none” by default).
<!--------------------------------------------------------------------------------->
<h3 id="layout-modes">Table layout modes</h3>
<p>
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'.
<!--------------------------------------------------------------------------------->
<h4 id="table-layout-property">The Table-Layout property</h4>
<pre class='propdef'>
Name: table-layout
Value: auto | fixed
Initial: auto
Applies To: table-root elements.
Inherited: yes
</pre>
<p class="advisement">
The computed value of the 'table-layout' property is equal to its specified value,
except if the specified width of the table root is not a <length-percentage>
in this case, the computed value of the property is always <code>auto</code>.
<p>
When the 'table-layout' property computes to <code>fixed</code>,
the content of the table-cells is ignored for the purpose of width computation
the aggregation algorithm for column sizing is not applied beyond the first row,
and the values explicitely specified for the table-columns and the first row of the table are used instead;
columns with undefinite 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: table-root elements.
Inherited: yes
</pre>
<p>
When the 'border-collapse' property has <code>collapse</code> as its value,
other properties like 'border-spacing' are not applied (see [[#collapsed-style-overrides]]),
and borders of adjacent cells are merged together such that each cell draws only half of the shared border
(see [[#border-collapsing]]).
<p>
A <a>table-root</a> element is said to be <dfn>rendered <dfn>in collapsed mode</dfn></dfn> in this case.
Otherwhise, the <a>table-root</a> element is said to be <dfn>rendered <dfn>in separated mode</dfn></dfn>.
<!--------------------------------------------------------------------------------->
<h4 id="caption-side-property">The Caption-Side property</h4>
<pre class='propdef'>
Name: caption-side
Value: top | bottom
Initial: top
Applies to: <code>table-caption</code> elements
Inherited: yes
Media: visual
</pre>
<p>
This property specifies the position of the caption box with respect to the table box.
Values have the following meanings:
<dl>
<dt><dfn id="caption-side-top">top</dfn>
<dd>
Positions the caption box above the table box.
<dt><dfn id="caption-side-bottom">bottom</dfn>
<dd>
Positions the caption box below the table box.
</dl>
<div class="issue">
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="issue">
Gecko also supports the "left" and "right" values. It was never well defined though.
<a href="http://codepen.io/FremyCompany/pen/YwGPWw">#REF</a>
</div>
<div classs="issue">
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">
<p>
To align caption content horizontally within the caption box, use the 'text-align' property.
<p>
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>
<p>
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>
<p>
The following rules apply to all table elements, irrespective of the layout mode in use:
<ul>
<li>The used value of 'display' for <a>table-track</a> and <a>table-track-grouping</a> elements is forced to contents.
This has the effect of not generating a box for these elements,
and making their table-cell children direct layout children of their parent <a>table-root</a> element.
<li>The used value of 'margin' for <a>table-cell</a> elements is forced to 0px.
<li>The used value of 'background' longhands for <a>table-cell</a> elements
is computed using a special background painting algorithm described in [[#drawing-cell-backgrounds]].
</ul>
<!--------------------------------------------------------------------------------->
<h4 id="collapsed-style-overrides">Overrides applying in collapsed-borders mode</h4>
<p>
When borders of a table are <a>rendered in collapsed mode</a>, the following rules apply:
<ul>
<li>The used value of 'padding' for the <a>table-root</a> element is forced to 0px.
<li>The used value of 'border-spacing' for the <a>table-root</a> element is forced to 0px.
<li>The used value of 'border-radius' for <a>table-cell</a> elements
is forced to 0px for all corners which are not shared with the <a>table-root</a> element.
For corners shared with the <a>table-root</a> element,
the used value of the corresponding border-…-radius property is set to
the used value of the corresponding property on the parent <a>table-root</a> element
if that value is bigger than the value which would be used otherwise.
Next, set the used values of the table-root element border radiuses
to the ones of their corresponding table-cell
(this will prevent the table radius to grow bigger than the corresponding cell).
<div class="issue">
This does not seem to be correct in either case, the cell border radius wins based on
this <a href="http://codepen.io/gregwhitworth/pen/LGWWZB" target="_blank">test</a>.