-
Notifications
You must be signed in to change notification settings - Fork 791
Expand file tree
/
Copy pathtables.src
More file actions
823 lines (695 loc) · 30.6 KB
/
tables.src
File metadata and controls
823 lines (695 loc) · 30.6 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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<!-- $Id: tables.src,v 1.30 1997-12-28 23:26:36 ijacobs Exp $ -->
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title>Tables</title>
<link rel="next" href="ui.html">
<link rel="previous" href="lists.html">
<link rel="STYLESHEET" href="style/default.css" type="text/css">
</head>
<body>
<h1 align="center"><a name="visual-tables">Tables</a></h1>
<p>Tables are used to show the relations between pieces of data, by
arranging them into labeled rows and columns. CSS2 assumes that the
data is already structured as a table, since its facilities for
rearranging elements are very limited.</p>
<p>Most of the CSS properties apply to table elements in the same
manner they apply to block-level elements. However, due to different
constraints on the size and position of cells, some properties behave
differently for tables. A few properties apply <em>only</em> to
tables.</p>
<h2><a name="table-elements">Table elements</a></h2>
<p>Table elements are those with <span
class="propinst-display">'display'</span> values of
<span class="index-inst" title="table">
<span class="value-inst-table">'table'</span> </span>, <span
class="index-inst" title="caption"><span
class="value-inst-caption">'caption'</span></span>, <span
class="index-inst" title="row"><span
class
8000
="value-inst-row">'row'</span></span>, <span class="index-inst"
title="column"><span
class="value-inst-col">'col'</span></span>, <span
class="index-inst" title="cell"><span
class="value-inst-cell">'cell'</span></span>, <span
class="index-inst" title="row-group"><span
class="value-inst-row-group">'row-group'</span></span>, or <span
class="index-inst" title="col-group"><span
class="value-inst-col-group">'col-group'</span></span>.
<p>All of these are treated as <span class="index-inst"
title="block"><span class="value-inst-block">'block'</span></span> if
their <span class="propinst-float">'float'</span> property is not
'none' or their <span class="propinst-position">'position'</span>
property is not 'static'.
<p>Any children of a <span class="index-inst" title="table"><span
class="value-inst-table">'table'</span></span>, <span
class="index-inst" title="row-group"><span
class="value-inst-row-group">'row-group'</span></span>, <span
class="index-inst" title="row"><span
class="value-inst-row">'row'</span></span> or <span class="index-inst"
title="cell"><span class="value-inst-cell">'cell'</span></span> that
are of type <span class="index-inst" title="block"><span
class="value-inst-block">'block'</span></span>, <span
class="index-inst" title="inline"><span
class="value-inst-inline">'inline'</span></span> or <span
class="index-inst" title="list-item"><span
class="value-inst-list-item">'list-item'</span></span> (and that are
non-floating and non-positioned), as well as all <a
href="flowobj.html#anonymous">anonymous</a> text boxes, will be put
inside a <em>virtual cell element</em>, that contains this child or
anonymous text box and all successors that are of type <span
class="index-inst" title="block"><span
class="value-inst-block">'block'</span></span>, <span
class="index-inst" title="inline"><span
class="value-inst-inline">'inline'</span></span> or <span
class="index-inst" title="list-item"><span
class="value-inst-list-item">'list-item'</span></span>, or anonymous.
<p>If the parent of a <span class="index-inst" title="cell"><span
class="value-inst-cell">'cell'</span></span> element, or of a virtual
cell element, is not a <span class="index-inst" title="row"><span
class="value-inst-row">'row'</span></span>, a <em>virtual row
element</em> will be created, which wil contain this element and all
its successors of type <span class="index-inst" title="cell"><span
class="value-inst-cell">'cell'</span></span>, until an element with a
different type, or the end of the parent.
<p>If the parent of a <span class="index-inst" title="row"><span
class="value-inst-row">'row'</span></span> element, or of a virtual
row element, is not a <span class="index-inst" title="row-group"><span
class="value-inst-row-group">'row-group'</span></span>, a <em>virtual
row-group element</em> is created, which will contain this element and
all successors of type <span class="index-inst" title="row"><span
class="value-inst-row">'row'</span></span>, until the next element
that has a different type, or the end of the parent.
<p>If the parent of a <span class="index-inst" title="row-group"><span
class="value-inst-row-group">'row-group'</span></span>, or of a
virtual row-group element, is not a <span class="index-inst"
title="table"><span class="value-inst-table">'table'</span></span>,
<em>a virtual table element</em> will be created, which contains this
element and all its successors of type <span class="index-inst"
title="row-group"><span
class="value-inst-row-group">'row-group'</span></span>, until an
element of a different type, or the end of the parent.
<p><span class="index-inst" title="col-group"><span
class="value-inst-col-group">'Col-group'</span></span> elements are
ignored (i.e,, treated as 'none') if they are not the
child of a <span class="index-inst" title="table"><span
class="value-inst-table">'table'</span></span>. <span
class="index-inst" title="col"><span
class="value-inst-col">'Col'</span></span> elements are ignored if
they are not the child of a <span class="index-inst"
title="table"><span class="value-inst-table">'table'</span></span> or
a <span class="index-inst" title="col-group"><span
class="value-inst-col-group">'col-group'</span></span>. Any content
and descendants of a 'col' are ignored. Any content or descendants of
a <span class="index-inst" title="col-group"><span
class="value-inst-col-group">'col-group'</span></span>, other than
<span class="index-inst" title="col"><span
class="value-inst-col">'col'</span></span>, are also ignored.
<div class=example>
<p>[Need example here]
</div>
<h2><a name="table-layout">Table layout</a></h2>
<p>A table is made up of one table element, several columns possibly
grouped into column groups, and several rowgroups, containing rows,
which in turn contain cells. (For speech style sheets, the cells are
further subdivided into header and data cells.) The spatial layout is
governed by a grid. All boxes that make up the table have to align
with the grid.</p>
<p>One can think of a table as built from six layers. Each layer hides
the lower layers from view, unless it is transparent (or has
transparent parts). See Figure 1.</p>
<object data="images/tbl-layers.gif">
<P>Figure 1. Schema of table layers.
<p><img src="images/tbl-layers.gif" alt="schema of table layers"></p>
</object>
<ol>
<li>
<p>The lowest layer is a single plane, representing the table box
itself. (Note that like all boxes, it may be transparent).</p>
</li>
<li>
<p>The next layer contains the column groups. The columns groups are
as tall as the table, but they need not cover the whole table
horizontally.</p>
</li>
<li>
<p>On top of the column groups are the areas representing the column
boxes. Like column groups, columns are as tall as the table, but need
not cover the whole table horizontally.</p>
</li>
<li>
<p>Next is the layer containing the row groups. Each row group is as
wide as the table. Together, the row groups completely cover the table
from top to bottom.</p>
</li>
<li>
<p>The last but one layer contains the rows. The rows also cover the
whole table.</p>
</li>
<li>
<p>The topmost layer contains the cells themselves, and the borders in
between them. As the figure shows, the cells don't have to cover the
whole table, but may leave "holes."</p>
</li>
</ol>
<p>To position the table elements, we assume a hypothetical grid,
consisting of an infinite number of columns and rows of "grid cells."
All table elements (table box, row boxes, cell boxes, etc.) are
rectangular and are aligned with the grid: they occupy a whole number
of grid cells, determined according to the following rules.</p>
<p>Columns are placed next to each other in the order they occur. Each
one occupies the number of grid columns given by its <span
class="propinst-column-span">'column-span'</span> property. A column
group occupies the same columns as the columns contained in it. The
first column may be either on the left or on the right, depending on
the value of the <span class="propinst-direction">'direction'</span>
property of the table.</p>
<p>Each row box occupies one row of grid cells. Together, the row
boxes fill the table from top to bottom in the order they occur in the
source document, or, stated differently: the table occupies exactly as
many grid rows as there are row elements.
<p>A row group occupies the same grid cells as the rows inside the row
group together.</p>
<p>Each cell occupies a rectangle of <span
class="propinst-column-span">'column-span'</span> grid cells wide and
<span class="propinst-row-span">'row-span'</span> grid cells high. The
top row of this rectangle of grid cells must be in the row occupied by
the cell's parent. The rectangle must be as far to the left as
possible, but may not overlap with any other cell, and must be to the
right of all cells in the same row that are earlier in the source
document. (If the <span class="propinst-direction">'direction'</span>
of the table is 'right-to-left', interchange "left" and "right" in the
previous sentence.) </p>
<p>Cells are <span class="propinst-row-span">'row-span'</span> high
only if there are enough rows: a cell cannot extend below the last row
box; it is made shorter until it fits.</p>
<p>Note that there may be "holes" left between the cells. These holes
are transparent, and the lower layers of the table are visible through
them. Example:</p>
<div class="example">
<PRE>
<STYLE>
TABLE {background: #ff0}
TD {background: red; border: double black}
</STYLE>
...
<TABLE>
<TR>
<TD> 1
<TD rowspan="2"> 2
<TD> 3
<TD> 4
</TR>
<TR>
<TD>
<TD colspan=2> 5
</TR>
</TABLE>
</PRE>
</div>
<p><img src="images/tbl-empty.gif" alt='table with a "hole" in lower
left corner'></p>
<H3><a name="row-col-props">Row and column properties</a>: <span
class="propinst-column-span">'column-span'</span>, and
<span class="propinst-row-span">'row-span'</span></H3>
<!-- #include src=properties/row-span.srb -->
<p>How many rows a cell spans. See <a href="#table-layout">"Table
layout"</a> above for a discussion of how it is used to lay out cells
in a table.
<!-- #include src=properties/column-span.srb -->
<p>How many columns a cell spans. A cell box occupies a rectangle of
<span class="propinst-column-span">'column-span'</span> by <span
class="propinst-row-span">'row-span'</span> grid cells in a table. An
example of its use is:</p>
<div class="example">
<pre>
[COLSPAN] {column-span: attr(COLSPAN)}
</pre>
<p>This rule is in the recommended <a href="sample.html">default (UA)
style sheet</a> for HTML 4.0.</p>
</div>
<h2>Computing widths and heights</h2>
<p>The principle for determining the width of each column is as
follows:</p>
<ol>
<li>
<p>The width is determined by the <span
class="propinst-width">'width'</span> property of the column box.</p>
</li>
<li>
<p>However, if there is no column box, or its 'width' is 'auto', the
width is given by the width requirements of the cells in the
column.</p>
</li>
<li>
<p>If the value of <span class="propinst-width">'width'</span> for the
first cell in the column is 'auto', the UA finds the "optimal" width
of the column, based on some heuristics.</p>
</li>
</ol>
<p>More details are given below.</p>
<p>The width of the table is given by its <span
class="propinst-width">'width'</span> property. If that is 'auto', the
width is the sum of the column widths. More precisely: the sum of the
columns and the borders between them. See <a
href="#border-placement">"Placement of the borders"</a> below.</p>
<p>Finding the optimal width is complicated. In many cases, what is
optimal is a matter of taste. CSS therefore doesn't define what the
optimal width of each column is; a UA is free to use whatever
heuristics is has, and is also free to prefer speed over precision.
There are a few implementation hints in chapter [???].</p>
<p>The width computation is complicated by cells that span columns and
by widths that are specified as percentages. The problem of finding
the widths can be regarded as a constraint resolution system, that
may be over- or under-constrained.</p>
<p>A percentage is relative to the table width. If the table's width
is 'auto', a percentage represents a constraint on the column's width,
which a UA should try to satisfy. (Obviously, this is not always
possible: if the column's width is '110%', the constraint cannot be
satisfied inside a table whose <span
class="propinst-width">'width'</span> is 'auto'.)</p>
<p>A cell that spans columns, provides a constraint on the sum of the
widths of the columns it spans.</p>
<p>If a cell's content doesn't "fit" the width of the column, the
<span class="propinst-overflow">'overflow'</span> property
determines what happens to it. Similarly, if the <span
class="propinst-width">'width'</span> of the table is not 'auto',
and the sum of the columns is not equal to the table's width, the
<span class="propinst-overflow">'overflow'</span> property of the
table determines what happens.</p>
<h2><a name="border-placement">Placement of the borders:</a> <span
class="propinst-cell-spacing">'cell-spacing'</span></h2>
<p>For block-level and inline elements, the position of the border
relative to the content of the element is determined by the margin
and the padding. But in a table, the positions of the borders are
constrained by the fact that they have to line up from one row to the
next and from one column to the next.</p>
<p>There are two distinct models for setting borders on table
cells. One is most suitable for so-called <span class="index-inst"
title="2½D borders">"2½D" borders</span> (<span class="index-inst"
title="ridge"><span class="value-inst-ridge">ridge</span></span>,
<span class="index-inst" title="groove"><span
class="value-inst-groove">groove</span></span>, <span
class="index-inst" title="inset"><span
class="value-inst-inset">inset</span></span>, and <span
class="index-inst" title="outset"><span
class="value-inst-outset">outset</span></span>) around individual
cells, the other is suitable for borders that are continuous from one
and of the table to the other. Many border styles can be achieved with
either model, so it is often a matter of taste which model is used.</p>
<p>The property <span
class="propinst-cell-spacing">'cell-spacing'</span> selects the model:
<!-- #include src=properties/cell-spacing.srb -->
<p>The 'cell-spacing' property only applies to elements with 'display:
table'.
<p>If the value is a length, that amount of space is kept open between
the borders of all cells. It may not be negative. The space is filled
with the background of the table element.</p>
<p>If there are two length values, the first one is the horizontal
spacing, and the second one is the vertical spacing. If there is just
one length value, it gives both the horizontal and vertical
spacing.</p>
<p>Each cell has its own borders, and the overall width of the table
is the sum of the cells, plus the cell-spacing between all borders
(see figure 3).</p>
<div class=figure>
<p><img src="images/tbl-spacing.gif" alt="A table with cell-spacing">
<p class=caption>Figure 3. A table with 'cell-spacing' set to a length
value. Note that each cell has its own border, and the table has a
separate border as well.
</div>
<p>In this mode, rows, columns, row-groups and column groups cannot
have borders. (The border properties on those elements are ignored.)
<div class=example>
<p>The table in figure 3 could be the result of a style sheet like
this:
<pre>
TABLE {border: outset 10pt; cell-spacing: 15pt}
TD {border: inset 5pt}
TD.special {border: inset 10pt} /* The top-left cell */
</pre>
</div>
<p>If the value of 'cell-spacing' is 'none', the model is more
complicated. In this mode it is possible to set borders on rows and
row-groups that extend all the way from one end of the table to the
other, and it is possible, e.g., to create tables with rules between
the cells, and no rules on the outside of the table.
<p>The borders are centered on the grid lines between the cells. A
renderer has to find a consistent rule for rounding off in the case of
an odd number of discrete units (screen pixels, printer dots).</p>
<p>The diagram below shows how the width of the table, the widths of
the borders, the padding and the cell width interact. Their relation
is given by the following equation, which holds for every row of the
table:</p>
<blockquote>
<p><var>table-width</var> = <var>border-width</var><sub>0</sub> +
<var>padding-left</var><sub>1</sub> + <var>width</var><sub>1</sub> +
<var>padding-right</var><sub>1</sub> +
<var>border-width</var><sub>1</sub> +
<var>padding-left</var><sub>2</sub> +...+
<var>padding-right</var><sub><var>n</var></sub> +
<var>border-width</var><sub><var>n</var></sub></p>
</blockquote>
<p>Here <var>n</var> is the number of cells in the row, and
<var>border-width</var><sub><var>i</var></sub> refers to the border
between cells <var>i</var> and <var>i</var> + 1.</p>
<p><img src="images/tbl-width.gif" alt="Schema showing the widths of cells and borders and the padding of cells"></p>
<p>Note that for a table element, using 'cell-spacing' 'none', the
width of the table includes half the border, and that a table doesn't
have a padding. It does have a margin, however.</p>
<h2>Conflict resolution for borders</h2>
<p>If 'cell-spacing' is 'none', the style of the borders between the
cells is found by comparing the border properties of all the boxes
(cells, columns, the table itself, etc.) that meet at that
border. Columns and rows can also have borders, but they are only
drawn when they coincide with a cell border.</p>
<p>To find the border style at each side of a grid cell, the following
properties have to be compared:</p>
<ol>
<li>
<p>Those of the one or two cells that have an edge here. Less than two
can occur at the edge of the table, but also at the edges of "holes"
(unoccupied grid cells).</p>
</li>
<li>
<p>Those of the columns that have an edge here.</p>
</li>
<li>
<p>Those of the column groups that have an edge here.</p>
</li>
<li>
<p>Those of the rows that have an edge here.</p>
</li>
<li>
<p>Those of the row groups that have an edge here.</p>
</li>
<li>
<p>Those of the table, if this is the edge of the table.</p>
</li>
</ol>
<p>This will give between 0 and 8 <span class="propinst-border">'border'</span> values. Each value is made
up of a <span class="propinst-border-width">'border-width'</span>,
<span class="propinst-border-color">'border-color'</span> and <span
class="propinst-border-style">'border-style'</span>. The border
with the largest width will be drawn. If there are two or more with
the same width, but different style, then the one with a style near
the start of the following list will be drawn:</p>
<blockquote>
<p>'blank', 'double', 'solid', 'dashed', 'dotted', 'ridge', 'groove',
'none'</p>
</blockquote>
<p>If the style is 'outset', it will be drawn as 'ridge' instead, and
'inset' will be drawn as 'groove'.</p>
<p>If the borders only differ in color, a color different from the
<span class="propinst-color">'color'</span> property of the two cells
on either side will be preferred over a color that only differs from
one of the cells, which in turn will be chosen over a border that
doesn't differ in color from the cells.</p>
<p>If none of these rules determine the color of the border, the UA is
free to choose one of the colors.</p>
<p>Here is an example:</p>
<div class="example">
<pre>
TD.blue {border: medium solid blue} TD.thick {border: thick solid red}
TD.double {border: thick double black} TR {border: medium dotted
green}
</pre>
</div>
<p>with this document:</p>
<div class="example">
<pre>
<table>
<tr><td>1<td class="blue">2<td>2
<tr><td>4<td class="thick">5<td>6
<tr><td>7<td class="double">8<td>9
</table>
</pre>
<p>This will be the result:</p>
<p><img src="images/tbl-border.gif" alt="Table with different border
styles"></p>
</div>
<div class=example>
<p>Here is a table with horizontal rules between the rows. The top
border of the table is set to 'blank' to suppress the top border of
the first row.
<pre>
TR {border-top: so
93CD
lid}
TABLE {border-top: blank}
</pre>
<p><img src="images/tbl-rules.gif" alt="Table with horizontal rules">
<p>In this case the same effect can also be achieved without setting a
'blank' border on TABLE, by addressing the first row separately. Which
method is preferred is a matter of taste.
<pre>
TR:first-child {border-top: none}
TR {border-top: solid}
</pre>
</div>
<h2>Properties for columns and rows</h2>
<p>Only four properties apply to a column box or column-group box:
<span class="propinst-border">'border'</span>, <span
class="propinst-background">'background'</span>, <span
class="propinst-width">'width'</span>, and <span
class="propinst-column-span">'column-span'</span>. The first two are
actually shorthand properties, so all the border properties and all
the background properties apply.</p>
<p>Only <span class="propinst-border">'border'</span> and <span
class="propinst-background">'background'</span> apply to a row or
row-group. But note that you can set inherited properties on rows and
row-groups, and they will be inherited by the cells.</p>
<h2>Vertical alignment of cells in a row</h2>
<p>The cells in a row are aligned somewhat like letters on a line.
Each cell, or rather each cell's content, has a baseline, a top, a
middle and a bottom, and so does the row itself. The value of the
<span class="propinst-vertical-align">'vertical-align'</span> property
of the cells determines on which of these lines they are aligned:</p>
<dl>
<dt>baseline</dt>
<dd>
<p>the baseline of the cell is put at the same height as the baseline
of the row (see below for the definition of baselines of cells and
rows)</p>
</dd>
<dt>top</dt>
<dd>
<p>the top of the cell is aligned with the top of the row</p>
</dd>
<dt>bottom</dt>
<dd>
<p>the bottom of the cell is aligned with the bottom of the row</p>
</dd>
<dt>middle</dt>
<dd>
<p>the center of the cell is aligned with the center of the row</p>
</dd>
<dt>sub, super, text-top, text-bottom</dt>
<dd>
<p>these values do not apply to cells; the cell is aligned at the
baseline instead</p>
</dd>
</dl>
<p>The baseline of a cell is the baseline of the first line of text in
the cell. If there is no text, the baseline is the baseline of
whatever object is displayed in the cell, or, if it has none, the
bottom of the cell. The maximum distance between the top of the cell
and the baseline over all cells that have 'vertical-align:baseline' is
used to set the baseline of the row. Here is an example:</p>
<p><img src="images/cell-align.gif" alt="Example of vertically
aligning the cells"></p>
<p>Cells 1 and 2 are aligned at their baselines. Cell 2 has the largest
height above the baseline, so that determines the baseline of the row.
Note that if there is no cell aligned at its baseline, the row will
not have (not need) a baseline.</p>
<p>To avoid ambiguous situations, the alignment of cells proceeds in a
certain order. First the cells that are aligned on their baseline are
positioned. This will establish the baseline of the row. Next the
cells with alignment 'top' are positioned.</p>
<p>The row now has a top, possibly a baseline, and a provisional
height, which is the distance from the top to the lowest bottom of the
cells positioned so far. (See conditions on the cell padding
below.)</p>
<p>If any of the remaining cells, those aligned at the bottom or the
middle, have a height that is larger than the current height of the
row, the height of the row will be increased to the maximum of those
cells, by lowering the bottom.</p>
<p>Finally the remaining cells are positioned.</p>
<p>The area between the cell content and the border is part of the
cell's padding. The padding at the top and bottom of each cell after
positioning must be at least as large as the <span
class="propinst-padding">'padding'</span> property
specifies. The height of the row must be as small as possible without
violating this rule.</p>
<h2>Horizontal alignment of cells in a column</h2>
<p>A cell is similar to a block in the way its contents are rendered,
that means, in particular, that <span
class="propinst-text-align">'text-align'</span> applies to
it. However, tables also allow a way of aligning text that does not
apply to other blocks, and that is aligning the contents of several
cells so that they all align on, e.g., a decimal point (".")
<p>More precisely, if the value of 'alignment' for a certain cell is
a string, that cell has an <dfn>alignment point</dfn>, which is the
start of that string. The alignment point must be straight above or
below the alignment points of all other cells in the same column that
have an alignment point. (Note that the other cells do not need to
have the same value for <span
class="propinst-text-align">'text-align'</span>; as long as they are
aligned on a string, they have an alignment point.)
<p>Aligning text in this way is only useful if the text is short
enough not to be broken over several lines. The result is undefined if
the text <em>is</em> broken.
<p>If the string occurs more than once in the cell's content, the
alignment point is the start of the first occurrence.
<p>If the string doesn't occur, the alignment point is the end of the
content.
<h2><a name="table-captions">Table captions</a>: the <span
class="propinst-caption-side">'caption-side'</span> property</h2>
<!-- #include src=properties/caption-side.srb -->
[Values top-left, bottom-left, top-right and bottom-right also
proposed. They would make the caption into something similar to a
float.]
['top' means caption is a block above the t
CDD
able, 'bottom' means it is
a block after the table]
<h2><a name="generating-speech">Generating speech</a>: the <span
class="propinst-speak-header">'speak-header'</span> property</h2>
<!-- #include src=properties/speak-header.srb -->
<p>[Does 'speak-header' apply to TH or to TD?]
<p>When a table is spoken by a speech generator, the relation between
the data cells and the header cells must be expressed in a different
way than by horizontal and vertical alignment. Some speech browsers
may allow a user to move around in the 2-dimensional space, thus
giving them the opportunity to map out the spatially represented
relations. When that is not possible, the style sheet must specify at
which points the headers are spoken.</p>
<p>CSS supports two possibilities: the headers are spoken before every
cell, or only before a cell when that cell is associated with a
different header than the previous cell.</p>
<p>[Add speak:header-cell|data-cell, and some way to mirror the
axis/axes attributes? BB]</p>
<p>It is assumed that a speech UA analyzes the table as specified in
the HTML 4.0 specification, to find for each data cell the header
cells with which it is associated. In summary, the algorithm is to go
up in the column and find all header cells, and to go towards the
start of the row to find all header cells there. If a data cell is
found above a header cell, then the search for header cells in the
column stops there. Similarly, if a data cell is found in front of a
header cell, the search in that row stops.</p>
<p>Since sometimes header cells are not put in the column or row to
which they apply (see e.g., the cells "San Jose" and "Seattle" in the
example below), an explicit association using the AXIS and AXES
attributes must be made. The example below shows the required
mark-up</p>
<div class=example>
<p><img src="images/table1.gif" alt="image of a table created in Word"></p>
<p>This presents the money spent on meals, hotels and transport in two
locations (San Jose and Seattle) for successive days. Conceptually,
you can think of the table in terms of a n-dimensional space. The axes
of this space are: location, day, category and subtotal. Some cells
define marks along an axis while others give money spent at points
within this space. The HTML markup for this table is:</p>
<pre>
<TABLE>
<CAPTION>
Travel Expense Report
</CAPTION>
<TR>
<TH></TH>
<TH>Meals</TH>
<TH>Hotels</TH>
<TH>Transport</TH>
<TH>subtotal</TH>
</TR>
<TR>
<TH axis="san-jose">San Jose</TH>
</TR>
<TR>
<TH axes="san-jose">25-Aug-97</TH>
<TD>37.74</TD>
<TD>112.00</TD>
<TD>45.00</TD>
<TD></TD>
</TR>
<TR>
<TH axes="san-jose">26-Aug-97</TH>
<TD>27.28</TD>
<TD>112.00</TD>
<TD>45.00</TD>
<TD></TD>
</TR>
<TR>
<TH axes="san-jose">subtotal</TH>
<TD>65.02</TD>
<TD>224.00</TD>
<TD>90.00</TD>
<TD>379.02</TD>
</TR>
<TR>
<TH axis="seattle">Seattle</TH>
</TR>
<TR>
<TH axes="seattle">27-Aug-97</TH>
<TD>96.25</TD>
<TD>109.00</TD>
<TD>36.00</TD>
<TD></TD>
</TR>
<TR>
<TH axes="seattle">28-Aug-97</TH>
<TD>35.00</TD>
<TD>109.00</TD>
<TD>36.00</TD>
<TD></TD>
</TR>
<TR>
<TH axes="seattle">subtotal</TH>
<TD>131.25</TD>
<TD>218.00</TD>
<TD>72.00</TD>
<TD>421.25</TD>
</TR>
<TR>
<TH>Totals</TH>
<TD>196.27</TD>
<TD>442.00</TD>
<TD>162.00</TD>
<TD>800.27</TD>
</TR>
</TABLE>
</pre>
<p>By providing the data model in this way, authors make it
possible for speech enabled-browsers to explore the table in
rich ways, e.g. each cell could be spoken as a list, repeating the
applicable headers before each data cell:</p>
<pre>
San Jose, 25-Aug-97, Meals: 37.74
San Jose, 25-Aug-97, Hotels: 112.00
San Jose, 25-Aug-97, Transport: 45.00
...
</pre>
<p>The browser could also speak the headers only when they change:</p>
<pre>
San Jose, 25-Aug-97, Meals: 37.74
Hotels: 112.00
Transport: 45.00
26-Aug-97, Meals: 27.28
Hotels: 112.00
...
</pre>
</div>
<p>The 'speak-header' property of a header cell determines when
it is spoken: before every data cell, or only when the previous cell
spoken wasn't associated with this header.</p>
<h2>Table implementation notes</h2>
<p><em>[Move to appendix]</em></p>
<p>[Minimum/maximum]</p>
</body>
</html>
<!-- Keep this comment at the end of the file
Local variables:
mode:sgml
sgml-declaration:"~/SGML/HTML4.decl"
sgml-default-doctype-name:"html"
sgml-minimize-attributes:t
sgml-nofill-elements:("pre" "style" "br")
sgml-live-element-indicator:t
End:
-->