< Day Day Up > |
11.3 Table SizingNow that we've dug into the guts of table formatting and cell border appearance, we have the pieces we need to understand the sizing of tables and their internal elements. When it comes to determining table width, there are two different approaches: fixed-width layout and automatic-width layout. Heights are calculated automatically no matter what width algorithms are used. 11.3.1 WidthSince there are two different ways to figure out the width of a table, it's only logical that there be a way to declare which should be used for a given table. Authors can use the property table-layout to select between the two kinds of table width calculation.
While the two models can have different results in laying out a specific table, the more fundamental difference between the two is that of speed. With a fixed-width table layout, the user agent can calculate the layout of the table more quickly than is possible in the automatic-width model. 11.3.1.1 Fixed layoutThe main reason the fixed-layout model is so fast is that its layout does not depend on the contents of table cells. Instead, it's driven by the width values of the table, columns, and cells within that table. The fixed-layout model works in the following simple steps:
At that point, the width of the table is set to be either the value of width for the table or the sum of the column widths, whichever is greater. If the table turns out to be wider than its columns, then the difference is divided by the number of columns and added to each of them. This approach is fast because all of the column widths are defined by the first row of the table. The cells in any rows that come after the first are sized according to the column widths that were defined by the first row. The cells in those following rows do not change column widths, which means that any width value assigned to those cells will be ignored. In cases where a cell's content does not fit into its cell, the overflow value for the cell determines whether the cell contents are clipped, visible, or generate a scrollbar. Let's consider the following styles and markup, which are illustrated in Figure 11-11: table {table-layout: fixed; width: 400px; border-collapse: collapse;} td {border: 1px solid;} col#c1 {width: 200px;} #r1c2 {width: 75px;} #r2c3 {width: 500px;} <table> <colgroup> <col id="c1"><col id="c2"><col id="c3"><col id="c4"> </colgroup> <tr> <td id="r1c1">1-1</td><td id="r1c2">1-2</td> <td id="r1c3">1-3</td><td id="r1c4">1-4</td> </tr> <tr> <td id="r2c1">2-1</td><td id="r2c2">2-2</td> <td id="r2c3">2-3</td><td id="r2c4">2-4</td> </tr> <tr> <td id="r3c1">3-1</td><td id="r3c2">3-2</td> <td id="r3c3">3-3</td><td id="r3c4">3-4</td> </tr> <tr> <td id="r4c1">4-1</td><td id="r4c2">4-2</td> <td id="r4c3">4-3</td><td id="r4c4">4-4</td> </tr> </table> Figure 11-11. Fixed-width table layoutAs you can see in Figure 11-11, the first column is 200 pixels wide, which happens to be half the 400-pixel width of the table. The second column is 75 pixels wide because the first-row cell within that column has been assigned an explicit width. The third and fourth columns are each 61 pixels wide. Why? Because the sum of the column widths for the first and second columns (275px), plus the various borders between columns (3px), equals 278 pixels. 400 minus 278 is 122, and that divided in half is 61, so that's how many pixels wide the third and fourth columns will be. What about the 500-pixel width for #r2c3? It's ignored because that cell isn't in the first row of the table. Note that it is not absolutely necessary that the table have an explicit width to make use of the fixed-width layout model, although it definitely helps. For example, given the following, a user agent could calculate a width for the table that is 50 pixels narrower than the parent element's width. It would then use that calculated width in the fixed-layout algorithm: table {table-layout: fixed; margin: 0 25px; width: auto;} This is not required, however. User agents are also permitted to lay out any table with an auto value for width using the automatic-width layout model. 11.3.1.2 Automatic layoutThe automatic-layout model, while not as fast as fixed layout, is probably much more familiar to you because it's substantially the same model that HTML tables have used for years. In most current user agents, use of this model will be triggered by a table having a width of auto, regardless of the value of table-layout, although this is not assured. The reason automatic layout is slower is that the table cannot be laid out until the user agent has looked at all of the content of the table. That is, it requires that the user agent lay out the entire table each time it gets a new cell. This generally requires the user agent to perform some calculations and then go back through the table to perform a second set of calculations. The content has to be fully examined because, as with HTML tables, the table's layout is dependent on the content in all the cells. If there is a 400-pixel-wide image in a cell in the last row, then it will force all of the cells above it (those in the same column) to be 400 pixels wide. Thus, the width of every cell has to be calculated, and adjustments must be made (possibly triggering another round of content-width calculations) before the table can be laid out. The details of the model can be expressed in the following steps:
In addition, the user agent must take into account that when a column width has a percentage value for its width, the percentage is calculated in relation to the width of the table—even though it doesn't yet know what that will be! It instead has to hang on to the percentage value and use it in the next part of the algorithm. At this point, the user agent will have figured how wide or narrow each column can be. With that information in hand, it can then proceed to actually figuring out the width of the table. This happens as follows:
Once the last step is completed, then, and only then, can the user agent actually lay out the table. The following styles and markup, presented in Figure 11-12, help illustrate how this process works: table {table-layout: auto; width: auto; border-collapse: collapse;} td {border: 1px solid;} col#c3 {width: 25%;} #r1c2 {width: 40%;} #r2c2 {width: 50px;} #r2c3 {width: 35px;} #r4c1 {width: 100px;} #r4c4 {width: 1px;} <table> <colgroup> <col id="c1"><col id="c2"><col id="c3"><col id="c4"> </colgroup> <tr> <td id="r1c1">1-1</td><td id="r1c2">1-2</td> <td id="r1c3">1-3</td><td id="r1c4">1-4</td> </tr> <tr> <td id="r2c1">2-1</td><td id="r2c2">2-2</td> <td id="r2c3">2-3</td><td id="r2c4">2-4</td> </tr> <tr> <td id="r3c1">3-1</td><td id="r3c2">3-2</td> <td id="r3c3">3-3</td><td id="r3c4">3-4</td> </tr> <tr> <td id="r4c1">4-1</td><td id="r4c2">4-2</td> <td id="r4c3">4-3</td><td id="r4c4">4-4</td> </tr> </table> Figure 11-12. Automatic table layoutLet's consider what happened for each of the columns, in turn:
The user agent now knows that the four columns have minimum and maximum widths as follows:
Thus, the table's minimum width is the sum of all the column minima plus the borders, which totals 215 pixels. The table's maximum width is 130px + 65%, which works out to be 371.42857143 pixels (given that 130px represents 35% of the overall table width). Let's assume this to be, after rounding the fractional number off to 371 pixels, the width value user agents will actually use. Thus, the second column will be 148 pixels wide, and the third column will be 93 pixels wide. It is not required that user agents actually use the maximum value; they may choose another course of action. Of course, this was (although it may not seem like it) a very simple and straightforward example: all of the content was basically the same width, and most of the declared widths were pixel lengths. In a situation where a table contains spacer GIFs, paragraphs of text, form elements, and so forth, the process of figuring out the table's layout is likely to be a great deal lengthier. 11.3.2 HeightAfter all of the effort that was expended in figuring out the width of the table, you might well wonder how much more complicated height calculation will be. Actually, in CSS terms, it's pretty simple, although browser developers probably don't think so. The easiest situation to describe is one in which the height is explicitly set via the height property. In such cases, the height of the table is defined by the value of height. This means that a table may be taller or shorter than the sum of its row heights. In such cases, the CSS2.1 specification explicitly refuses to define what should happen, instead noting that the issue may be resolved in future versions of CSS. A user agent could expand or shrink a table's rows to match its height, or implement a scrollbar to get to overflowing rows, or neither, or something completely different. It's up to each user agent to decide. If the height of the table is auto, then its height is the sum of the heights of all the rows within the table, plus any borders and cell spacing. To determine the height of each row, the user agent goes through a process similar to that used to find the widths of columns. It calculates a minimum and maximum height for the contents of each cell and then uses these to derive a minimum and maximum height for the row. After having done this for all the rows, the user agent figures out what each row's height should be, stacks them all on top of each other, and uses that calculation to determine the table's height. It's a lot like inline layout, only with less certainty in how things should be done. In addition to what to do about tables with explicit heights and how to treat row heights within them, you can add the following to the list of things CSS2.1 does not define:
As you can see, height calculations in tables are largely left up to user agents to figure out. Historical evidence would suggest that this will lead to each user agent doing something different, so you should probably avoid setting heights as much as possible. 11.3.3 AlignmentIn a rather interesting turn of events, alignment of content within cells is a lot better defined than cell and row heights. This is true even for vertical alignment, which could quite easily affect the height of a row. Horizontal alignment is the simplest. To align content within a cell, you use the text-align property. In effect, the cell is treated as a block-level box and all of the content within it is aligned as per the text-align value. (For details on text-align, see Chapter 6.) To vertically align content in a table cell, vertical-align is the relevant property. It uses many of the same values that are used for vertically aligning inline content, but the meanings of those values change when applied to a table cell. To summarize the three simplest cases:
These are illustrated in Figure 11-13, which uses the following styles and markup: table {table-layout: auto; width: 20em; border-collapse: separate; border-spacing: 3px;} td {border: 1px solid; background: silver; padding: 0;} div {border: 1px dashed gray; background: white;} #r1c1 {vertical-align: top; height: 10em;} #r1c2 {vertical-align: middle;} #r1c3 {vertical-align: bottom;} <table> <tr> <td id="r1c1"> <div> The contents of this cell are top-aligned. </div> </td> <td id="r1c2"> <div> The contents of this cell are middle-aligned. </div> </td> <td id="r1c3"> <div> The contents of this cell are bottom-aligned. </div> </td> </tr> </table> Figure 11-13. Vertical alignment of cell contentsIn each case, the alignment is carried out by automatically increasing the padding of the cell itself to achieve the desired effect. In the first cell in Figure 11-13, the bottom padding of the cell has been changed to equal the difference between the height of the cell's box and the height of the content within the cell. For the second cell, the top and bottom padding of the cell have been reset to be equal, thus vertically centering the content of the cell. In the last cell, the cell's top padding has been altered. The fourth possible value alignment is baseline, and it's a little more complicated that the first three:
It's easiest to provide an illustration (see Figure 11-14) and then discuss what's happening. Figure 11-14. Baseline alignment of cell contentsA row's baseline is defined by the lowest initial cell baseline (that is, the baseline of the first line of text) out of all its cells. Thus, in Figure 11-14, the row's baseline was defined by the third cell, which has the lowest initial baseline. The first two cells then have a baseline of their first line of text aligned with the row's baseline. As with top, middle, and bottom alignment, the placement of baseline-aligned cell content is accomplished by altering the top and bottom padding of the cells. In cases where none of the cells in a row are baseline-aligned, the row does not even have a baseline—it doesn't really need one. The detailed process for aligning cell contents within a row is as follows:
The vertical-align values sub, super, text-top, and text-bottom are ignored when applied to table cells. Thus, the following rule would have the same result as that shown in Figure 11-14: th {vertical-align: text-top;} |
< Day Day Up > |