One of the nice options with CSS3 is the ability to assign tbody styling to table rows and columns; you can also specify either even or odd rows using the nth-child property, which will be demonstrated in the second example. This is a boon for styling tables of data which typically would require either manual color coding for alternate rows or utilizing table formatting features in text editors such as Dreamweaver, which assign styling directly to the HTML. Creating styling rules in your CSS allows greater options for various types of table presentations.

For this demonstration we will use static data, and this will be the base table structure for use in both examples; however, data from dynamic database sources would work just as easily:

<table class="table_2" summary="Wholesale and retail and prices for popular produce at several farmers markets">
    <caption>
    <strong>Wholesale and retail prices for popular produce at several farmers markets</strong>
    </caption>
       <thead>
               <tr>
                     <th scope="row">Local Fresh</th>
                     <th scope="col" abbr="Beets">Beets</th>
                     <th scope="col" abbr="Broccoli">Broccoli</th>
                     <th scope="col" abbr="Carrots">Carrots</th>
                     <th scope="col" abbr="Leaf Lettuce">Leaf Lettuce</th>
                            <th scope="col" abbr="Radish">Radish</th>
                     <th scope="col" abbr="Tomatoes">Tomatoes</th>
               </tr>
       </thead>
       <tfoot>
       <tr>
               <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
               <tr>
                     <th scope="row">Avg Discount</th>
                     <td>$ .75</td>
                     <td>$ .90</td>
                     <td>$ .90</td>
                     <td>$ .85</td>
            <td>$ .90</td>
            <td>$ .90</td>
               </tr>
       </tfoot>
       <tbody>
               <tr>
                     <th scope="row">Wholesale</th>
                     <td>$ .75</td>
                     <td>$ .85</td>
                     <td>$ .30</td>
                     <td>$ .95</td>
            <td>$ .65</td>
            <td>$ 1.25</td>
               </tr>
               <tr>
                     <th scope="row">Retail</th>
                     <td>$1.50</td>
                     <td>$ 1.45</td>
                     <td>$ .85</td>
                     <td>$ 1.95</td>
            <td>$ 1.35</td>
            <td>$ 2.65</td>
               </tr>
               <tr>
                     <th scope="row">Discounts</th>
                       <td><span class="check"></span></td>
                       <td><span class="check"></span></td>
                       <td><span class="check"></span></td>
                       <td><span class="check"></span></td>
            <td><span class="check"></span></td>
            <td>&nbsp;</td>
         </tr>
      <tr>
               <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
      </tr>
      <tr>
       <thead>
               <tr>
                   <th scope="row">Regional Fresh</th>
                   <th scope="col" abbr="Beets">Beets</th>
                   <th scope="col" abbr="Broccoli">Broccoli</th>
                   <th scope="col" abbr="Carrots">Carrots</th>
                   <th scope="col" abbr="Leaf Lettuce">Leaf Lettuce</th>
                   <th scope="col" abbr="Radish">Radish</th>
                          <th scope="col" abbr="Tomatoes">Tomatoes</th>
               </tr>
        </thead>
               </tr>
               <tr>
                      <th scope="row">Wholesale</th>
                      <td>$ .70</td>
                      <td>$ .82</td>
                      <td>$ .27</td>
                      <td>$ .88</td>
                      <td>$ .62</td>
                      <td>$ 1.18</td>
               </tr>
               <tr>
                     <th scope="row">Retail</th>
                     <td>$ 1.40</td>
                     <td>$ 1.35</td>
                     <td>$ .75</td>
                     <td>$ 1.75</td>
            <td>$ 1.25</td>
            <td>$ 2.25</td>
               </tr>
               <tr>
                       <th scope="row">Discounts</th>
                       <td><span class="check"></span></td>
                       <td><span class="check"></span></td>
                       <td><span class="check"></span></td>
                       <td>&nbsp;</td>
                       <td><span class="check"></span></td>
                            <td><span class="check"></span></td>
               </tr>
       </tbody>
</table>

I have also added a few accessibility items to the table (i.e., the summary and caption) however, this piece will concentrate more on CSS3 functionality than accessibility, which will be a topic for another post.

In this example, we have all the elements that a typical data table needs, including a header, a body, and footer. In this tutorial, we will use several fresh produce market price comparisons which include popular vegetables for the table. The following two styles can be applied to this table by changing the class to table_1, and table_2.

Blue Gradient Table Color Scheme (Table 1)

The first table will be styled in blue color tones with some gradients for the descriptive cells and the “th” elements. In order for the table to have a small space between the cells, I’ve added the border-collapse separate property as you see below.

table.table_1{
    font-family: Cambria, serif;
    font-size: 17px;
    font-weight: normal;
    line-height: 1.4em;
    font-style: normal;
    text-transform: normal;
    border-collapse: separate;
}

In the styling for the head “th” elements, I’ve added a background with three gradient styling colors with rgb color stops for -webkit- and rgb percents for -moz- prefixes; I added a rounded border radius for the top left and top right corners, along with a modest 5px padding to keep the contents well spaced, and then added a solid bottom border color with a height of 3 pixels.

.table_1 th{
    padding:5px;
    color:#fff;
    text-shadow:1px 1px 1px #3B4545;
    border:1px solid #3799CE;
    border-bottom:3px solid #6B81B1;
    background-color:#2B4478;
    background:
       -webkit-gradient(linear, left bottom, left top,
        color-stop(0.02, rgb(13,33,76)),
        color-stop(0.51, rgb(87,116,177)),
        color-stop(0.87, rgb(107,129,177))
        );
    background:
       -moz-linear-gradient(center bottom,
        rgb(13,33,76) 2%,
        rgb(87,116,177) 51%,
        rgb(107,129,177) 87%
        );
    -webkit-border-top-left-radius:5px;
    -webkit-border-top-right-radius:5px;
    -moz-border-radius:5px 5px 0px 0px;
    border-top-left-radius:5px;
    border-top-right-radius:5px;
}

Next, we need to address the empty “th” sections of the table. With CSS3, we are allowed to select an empty “th” and apply styling to it, as in this example:

.table_1 th:empty{
    background:transparent;
    border:none;
}

For the table footer “td” the font will be 20px, aligned center, with a 1px text shadow for a standout effect, padding of 5px and 10px, a slightly darker blue background, border radius of 3px on all corners, and for the footer, “th” the font color will be a light tan hue:

.table_1 tfoot td{
    color: #D4B476;
    font-size:20px;
    text-align:center;
    padding:5px 10px;
    text-shadow:1px 1px 1px #3B352B;
    background-color:#6B81B1;
    -moz-border-radius:3px;
    -webkit-border-radius:3px;
}
.table_1 tfoot th{
    color:#D4B476;

}

The inner cells with the pricing data content will have a light blue background with a light text shadow for another standout effect, a 2px border and rounded 2px radius on all corners, which will create a shadow effect:

.table_1 tbody td{
    padding:10px;
    text-align:center;
    background-color:#CAE2F3;
    border: 2px solid #E0E6EF;
    -moz-border-radius:2px;
    -webkit-border-radius:2px;
    border-radius:2px;
    color:#666;
    text-shadow:1px 1px 1px #fff;
}

And to indicate which vegetables can be discounted at each market, I’ve added a span with a “check” class, i.e.,<span class=”check”></span> to all the cells for vegetables that would be indicated with a discount. This styling property allows the addition of specific content such as the check mark image in this example, and the ::before or ::after indication stipulates where it is inserted — either before or after other content contained within the element — this is all represented with the following CSS to call the style:

.table_1 tbody span.check::before{
    content : url(images/Check_01.png)
}

The blue gradient background table is displayed in Figure A below as displayed in Firefox 7.0.1:

Alternating Rows Ivory and Red Color Scheme (Table 2)

For the second example, I will add in styling for alternating row color effects. In addition to the nth-child property which is displayed toward the bottom of this example, I have also updated several of the styles from the first example.

For the base table style, I’ve changed the font family to Courier New, the size to 18px, and the border collapse to collapse so that there will be little space between cells. All stylings in this example are referenced by changing the class to “table_2”.

table.table_2{
    font-family:"Courier New", Courier;
    font-size: 18px;
    font-weight: normal;
    line-height: 1.2em;
    font-style: normal;
    text-transform: normal;
    border-collapse: collapse;
}

The table “th” has been updated also with new colors for the gradient, and borders representing several shades of and ivory color scheme.

.table_2 th{
    padding:5px;
    color:#fff;
    text-shadow:1px 1px 1px #999481;
    border:1px solid #D7D5CE;
    border-bottom:3px solid #D7D5CE;
    background-color:#2B4478;
    background:
        -webkit-gradient(linear, left bottom, left top,
        color-stop(0.02, rgb(153,148,129)),
        color-stop(0.51, rgb(215,213,206)),
        color-stop(0.87, rgb(248,248,248))
        );
    background:
        -moz-linear-gradient(center bottom,
        rgb(153,148,129) 2%,
        rgb(215,213,206) 51%,
        rgb(248,248,248) 87%
        );
    -webkit-border-top-left-radius:5px;
    -webkit-border-top-right-radius:5px;
    -moz-border-radius:5px 5px 0px 0px;
    border-top-left-radius:5px;
    border-top-right-radius:5px;
}

The empty “th” styling again:

.table_2 th:empty{
    background:transparent;
    border:none;
}

Below are the tfoot “td” and “th” styles with an updated color for contents, text-shadow, and background color:

.table_2 tfoot td{
    color: #D4B476;
    font-size:22px;
    text-align:center;
    padding:5px 10px;
    text-shadow:1px 1px 1px #999481;
       background-color:#D7D5CE;
}
.table_2 tfoot th{
    color:#D4B476;
}

The tbody “td” style with an updated text-shadow and the border radius styles omitted:

.table_2 tbody td{
    padding:5px;
    text-align:center;
    color:#666;
    text-shadow:1px 1px 1px #5E553E;
}

And the check images span styling for this example:

.table_2 tbody span.check::before{
    content: url(images/check_2.png);
}

Now, for the alternating rows continuing in the ivory color scheme with these CSS3 styles, note the use of nth-child(odd) and nth-child(even):

.table_2 tbody td {
       background:rgb(176,172,158);
       padding-top:4px;
}
.table_2 tbody tr:nth-child(odd) td {
       background:rgb(153,148,129);
       color:rgb(248,248,248);
}
.table_2 tr:nth-child(even) td {
       background::rgb(215,213,206);
       color:rgb(51,51,51);
}

With this styling the alternating even and odd rows will reset with each “thead”, and will continue throughout the remainder of that table section only.

The resulting table with the ivory and red color scheme is displayed in Figure B below as displayed in Firefox 7.0.1:

There are many ways that data tables can be styled with CSS3, allowing unlimited options for your web sites data display designs. The source code and associated CSS and image files are available for download and are best viewed in Firefox (unzip files to a folder and click the HTML file).