< Day Day Up > |
11.2 Table Cell BordersThere are actually two quite distinct border models in CSS. The separated border model takes effect when cells are separated from each other in layout terms. The other option is the collapsed border model, in which there is no visual separation between cells, and cell borders merge, or collapse, with each other. This latter is the default model. An author can choose between the two models with the property border-collapse.
The whole point of this property is to offer the author a way to determine which border model the user agent will employ. If the value collapse is in effect, then the collapsing borders model is used. If the value is separate, then the separated borders model is used. We'll look at the latter model first, since it's actually much simpler to describe. 11.2.1 Separated Cell BordersIn this model, every cell in the table is separated from the other cells by some distance, and the borders of cells do not collapse into each other. Thus, given the following styles and markup, you would see the result shown in Figure 11-6: table {border-collapse: separate;} td {border: 3px double black; padding: 3px;} <table cellspacing="0"> <tr> <td>cell one</td> <td>cell two</td> </tr> <tr> <td>cell three</td> <td>cell four</td> </tr> </table> Figure 11-6. Separated (and thus separate) cell bordersNote that the cell borders touch but remain distinct from one another. The three lines between cells are actually the two double borders sitting right next to each other. The HTML attribute cellspacing was included in the example above in order to make sure the cells had no separation between them, but its presence is likely a bit troubling. After all, if you can define that borders be separate, then there ought to be a way to use CSS to alter the spacing between cells. Fortunately, there is. 11.2.1.1 Border spacingThere may be situations where you want the table cell borders to be separated by some distance. This can be easily accomplished with the property border-spacing, which provides a more powerful replacement for the HTML attribute cellspacing.
Either one or two lengths can be given for the value of this property. If you want all your cells separated by a single pixel, then border-spacing: 1px; would suffice. If, on the other hand, you want cells to be separated by one pixel horizontally and five pixels vertically, you'd write border-spacing: 1px 5px;. If two lengths are supplied, the first is always the horizontal separation, and the second is always the vertical. The spacing values are also applied between the borders of cells along the outside of a table and the padding on the table element itself. Given the following styles, you would get the result shown in Figure 11-7: table {border-collapse: separate; padding: 10px; border: 2px solid black;} td {border-spacing: 3px 5px; border: 1px solid gray;} td#squeeze {border-width: 5px;} Figure 11-7. Border spacing effects between cells and their enclosing tableIn Figure 11-7, there is a space 3 pixels wide between the borders of any two horizontally adjacent cells, and there are 13 pixels of space between the borders of the right- and left-most cells and the right and left borders of the table element. Similarly, the borders of vertically adjacent cells are 5 pixels apart, and the borders of the cells in the top and bottom rows are 15 pixels from the top and bottom borders of the table, respectively. The separation between cell borders is constant throughout the table, regardless of the border widths of the cells themselves. In the separated border model, borders cannot be set for rows, row groups, columns, and column groups. Any border properties declared for such elements must be ignored by a CSS-conformant user agent. 11.2.1.2 Handling empty cellsBecause every cell is, in a visual sense, distinct from all the other cells in the table, what do you do with cells that are empty (i.e., have no content)? You have two choices, which are reflected in the values of the empty-cells property.
If empty-cells is set to show, then the borders and background of an empty cell will be drawn, just as with table cells that have content. If the value is hide, then no part of the cell is drawn, just as if the cell were set to visibility: hidden. If a cell contains any content, it cannot be considered empty. "Content," in this case, includes not only text, images, form elements, and so on, but also the nonbreaking space entity ( ) and any other whitespace except the CR (carriage-return), LF (linefeed), tab, and space characters. If all the cells in a row are empty, and all have an empty-cells value of hide, then the entire row is treated as if the row element were set to display: none.
11.2.2 Collapsing Cell BordersWhile the collapsing cell model largely describes how HTML tables have always been laid out when they don't have any cell spacing, it is quite a bit more complicated than the separated borders model. There are also some rules that set collapsing cell borders apart from the separated borders model. These are:
We'll explore the last two points in more detail in the next two sections. 11.2.2.1 Collapsing border layoutIn order to better understand how the collapsing-borders model works, let's look at the layout of a single table row, as shown in Figure 11-8. Figure 11-8. The layout of a table row using the collapsing-borders modelFor each cell, the padding and content width of the cell is inside the borders, as expected. For the borders between cells, half of the border is to one side of the grid line between two cells, and the other half is to the other side. In each case, only a single border is drawn along each cell edge. You might think that half of each cell's border is drawn to each side of the grid line, but that's not what happens. For example, assume that the solid borders on the middle cell are green and the solid borders on the outer two cells are red. The borders on the right and left sides of the middle cell (which collapse with the adjacent borders of the outer cells) will be all green, or all red, depending on which border wins out. We'll discuss how to tell which one wins in the next section. You may have noticed that the outer borders protrude past the table's width. This is because, in this model, half the table's borders are included in the width. The other half sticks out beyond that distance, sitting in the margin itself. This might seem a bit weird, but that's how the model is defined to work. The specification includes a layout formula that I'll reproduce here for the benefit of those who enjoy such things: row width = (0.5 * border-width0) + padding-left1 + width1 + padding-right1 + border-width1 + padding-left2 +...+ padding-rightn + (0.5 * border-widthn) Each border-widthi refers to the border between cell i and the next cell; thus, border-width3 refers to the border between the third and fourth cells. The value n stands for the total number of cells in the row. There is a slight exception to this mechanism. When beginning the layout of a collapsed-border table, the user agent computes an initial left and right border for the table itself. It does this by examining the left border of the first cell in the first row of the table and by taking half of that border's width as the table's initial left border width. The user agent then examines the right border of the last cell in the first row and uses half that width to set the table's initial right border width. For any row after the first, if the left or right border is wider than the initial border widths, it sticks out into the margin area of the table. In cases where a border is an odd number of display elements (pixels, printer dots, etc.) wide, the user agent is left to decide what to do about centering the border on the grid line. It might shift the border so that it is slightly off-center, round up or down to an even number of display elements, or anything else that seems reasonable. 11.2.2.2 Border collapsingWhen two or more borders are adjacent, they collapse into each other. In fact, they don't collapse so much as fight it out to see which of them will gain supremacy over the others. There are some strict rules governing which borders will win and which will not:
The following styles and markup, presented in Figure 11-9, help illustrate each of the four rules: table {border-collapse: collapse; border: 3px outset gray;} td {border: 1px solid gray; padding: 0.5em;} #r2c1, #r2c2 {border-style: hidden;} #r1c1, #r1c4 {border-width: 5px;} #r2c4 {border-style: double; border-width: 3px;} #r3c4 {border-style: dotted; border-width: 2px;} #r4c1 {border-bottom-style: hidden;} #r4c3 {border-top: 13px solid silver;} <table> <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-9. Manipulating border widths, styles, and colors leads to some unusual resultsLet's consider what happened for each of the cells, in turn:
This is, in fact, about as complicated as it sounds, although the behaviors are largely intuitive and make a little more sense with practice. It's worth noting, though, that the basic Netscape 1-era HTML table presentation can be captured with a fairly simple set of rules, described here and illustrated by Figure 11-10: table {border-collapse: collapse; border: 2px outset gray;} td {border: 1px inset gray;} Figure 11-10. Reproducing old-school table presentation |
< Day Day Up > |