DekGenius.com
Previous Section  < Day Day Up >  Next Section

11.2 Table Cell Borders

There 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.

border-collapse


Values

collapse | separate | inherit


Initial value

separate


Applies to

elements with the display value table or table-inline


Inherited

yes


Computed value

as specified


Note:

in CSS2, the default was 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 Borders

In 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 borders
figs/css2_1106.gif

Note 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 spacing

There 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.

border-spacing


Values

<length> <length>? | inherit


Initial value

0


Applies to

elements with the display value table or table-inline


Inherited

yes


Computed value

two absolute lengths


Note

property is ignored unless border-collapse value is separate


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 table
figs/css2_1107.gif

In 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 cells

Because 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.

empty-cells


Values

show | hide | inherit


Initial value

show


Applies to

elements with the display value table-cell


Inherited

yes


Computed value

as specified


Note

property is ignored unless border-collapse value is separate


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 (&nbsp;) 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.

As of this writing, empty-cells is not fully supported by Internet Explorer.


11.2.2 Collapsing Cell Borders

While 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:

  • Table elements cannot have any padding, although they can have margins. Thus, there is never separation between the border around the outside of the table and its outermost cells.

  • Borders can be applied to cells, rows, row groups, columns, and column groups. The table element itself can, as always, have a border.

  • There is never any separation between cell borders. In fact, borders collapse into each other where they adjoin, so that only one of the collapsing borders is actually drawn. This is somewhat akin to margin collapsing, where the largest margin wins. When cell borders collapse, the "most interesting" border wins.

  • Once they are collapsed, the borders between cells are centered on the hypothetical grid lines between the cells.

We'll explore the last two points in more detail in the next two sections.

11.2.2.1 Collapsing border layout

In 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 model
figs/css2_1108.gif

For 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 collapsing

When 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:

  • If one of the collapsing borders has a border-style of hidden, it takes precedence over all other collapsing borders. All borders at this location are hidden.

  • If one of the collapsing borders has a border-style of none, it takes the lowest priority. There will be no border drawn at this location unless all of the colliding borders have a value of none. Note that none is the default value for border-style.

  • If at least one of the collapsing borders has a value other than none or hidden, then narrow borders lose out to wider ones. If more than one of the collapsing borders have the same width, then the border style is taken in the following order, from most to least preferred: double, solid, dashed, dotted, ridge, outset, groove, inset. Thus, if two borders with the same width are collapsing, and one is dashed while the other is outset, the border at that location will be dashed.

  • If collapsing borders have the same style and width, but differ in color, then the color used is taken from an element in the following list, from most preferred to least: cell, row, row group, column, column group, table. Thus, if the borders of a cell and a column (identical in every way except color) collapse, then the cell's border color (and style and width) will be used. If the collapsing borders come from the same type of element, such as two row borders with the same style and width but different colors, then the behavior is not defined. The user agent decides what to do in such cases.

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 results
figs/css2_1109.gif

Let's consider what happened for each of the cells, in turn:

  • For cells 1-1 and 1-4, the 5-pixel borders were wider than any of their adjacent borders, so they won out not only over adjoining cell borders, but over the border of the table itself. The only exception is the bottom of cell 1-1, which was suppressed.

  • The bottom border on cell 1-1 was suppressed because cells 2-1 and 2-2, with their explicitly hidden borders, completely remove any borders from the edge of the cells. Again, the table's border lost out (on the left edge of cell 2-1) to a cell's border. The bottom border of cell 4-1 was also hidden, and so it prevented any border from appearing below the cell.

  • The 3-pixel double border of cell 2-4 was overridden on top by the 5-pixel solid border of cell 1-4. 2-4's border, in turn, overrode the border between itself and cell 2-3 because it was both wider and "more interesting," and it overrode the border between itself and cell 3-4, even though both are the same width, because 2-4's double style is defined to be "more interesting" than 3-4's dotted border.

  • The 13-pixel bottom silver border of cell 3-3 not only overrode the top border of cell 4-3, but it also affected the layout of content within both cells and the rows that contain both cells.

  • For cells along the outer edge of the table that aren't specially styled, their 1-pixel solid borders are overridden by the 3-pixel outset border on the table element itself.

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
figs/css2_1110.gif
    Previous Section  < Day Day Up >  Next Section