CSS3 selectors

Explanation

This is a demo for the CSS3 selectors, based on a table stylization. Please, click on the next and previous buttons to scan the slides. The associated article is here.

Step 0/12

Lorem ipsum dolor consectetur nunc
hendrerit viverra orci vestibulum commodo
fusce a dui tortor nulla vehicula
dolor vitae dictum duis vel
lobortis mi cras pellentesque neque ac
eleifend sollicitudin nulla augue semper
cras nunc scelerisque in malesuada
turpis velit eu lectus mi

Simple table

We write a simple table with standard HTML. We do not have any classes, only a clean/virgin table. It looks like:

<table>
  <thead>
    <tr>
      <th>...</th>
      ...
      <th>...</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>...</td>
      ...
      <td>...</td>
    <tr>
    ...
    <tr>
      <td>...</td>
      ...
      <td>...</td>
    <tr>
  </tbody>
</table>

First dress

We just stylize the table to get a simple base.

Here, we use a font property, with a text-align. We deal with borders with the help of border-spacing and border-radius. Finally, we add a box-shadow and a background. Very simple.

th

Here, we select all the th tags. table th is equivalent to thead > tr > th.

We know how to do this. It is a basic CSS selector.

th:first-of-type

But now, we just want to select the very first th. It means that we want to select the first tag which is a th, so the first of type th.

To select the last, we also have the last-of-type pseudo-class, and of course the nth-of-type.

tbody tr:nth-child(odd)

If we want to select all the nth element, we can use the nth-* pseudo-class. All pseudo-classes understand the an+b syntax. It means, to select all the even elements, we use 2n; to select all the odd elements, we use the 2n+1 elements; to select all third elements, we use 3n. In other words, this matches the bth child of an element after all the children have been split into groups of a elements each (read the specification).

CSS3 proposes two keywords: even and odd that respectively mean 2n and 2n+1.

tbody tr:nth-child(even)

And the same things with the even rows.

t(h|r):first-of-type

Now, a behaviour that could not be possible before.

We would like to select to first column to add a padding. It is very easy with the CSS3 selectors. Just select the first of type th and tr, it will select all first cells, so the first column.

t(h|r):last-of-type

We can see the padding.

And now, the same thing with the last-of-type pseudo-class.

Applause…

The final source?

table {
    font: 90%/1.5em "Lucida Grande", Geneva,
                    "DejaVu Sans", "Bitstream Vera Sans", AnjaliOldLipi,
                    "Lucida sans", "Trebuchet MS", Arial, Verdana;
    text-align: center;
    border: 4px black double;
    border-spacing: 0;
    -moz-border-radius: 12px;
    -moz-box-shadow: #6a3d37 5px 5px 6px;
    -webkit-border-radius: 12px;
    -webkit-box-shadow: #6a3d37 5px 5px 6px;
    border-radius: 12px;
    box-shadow: #6a3d37 5px 5px 6px;
    background: #b59d5c
}

th {
    color: #fff;
    font-size: 110%;
    text-shadow: #6a3d37 2px 2px 2px
}

    th:first-of-type {
        font-weight: bold;
        font-style: italic
    }

tbody tr:nth-child(odd) {
    color: #e0d8cb;
    background: #474644
}

tbody tr:nth-child(even) {
    color: #6a3d37
}

th:first-of-type,
td:first-of-type {
    padding: 0 0 4em 0
}

th:last-of-type,
td:last-of-type {
    padding: 0 4em 0 0
}

But… nth-last-child

We considere that the two last rows are not very important. How to select them to set their opacity to 0.75?

Let use the nth-last-child with a “tricky” an+b expression. We would like to count from the end and not from the beginning, that's we use the nth-last-child pseudo-class. But, to select only two rows, we do not split rows in groups, so a is set to -1. And, because of we want two rows, b is set to 2. Thus:

tbody tr:nth-last-child(-n+2) {
    opacity: .75
}

will select only the last rows.

Headache ensured

Now, we would like to combined many pseudo-classes (and introduced a new one).

Ok. We would like to select the row number 1, number 4 and number 7. The “Mathematical” expression is not so simple as we hoped. The tips is as follow: we split our rows in groups of 3, like this: 3n. But it will select the rows number 3, 6 and 9. No problem. In these groups, we will select the first element, so 3n+1 (or 3n-2 if you like to complicate things).

Yes, it's good, but it will select a row in our two last non-opaque rows. Hmm… Ideally, we should say: select the first row of each groups of three rows, but not the last row (which will be selected, because the last is the 7th row). Simple. We are going to use the not pseudo-class, combined with the last-child pseudo-class (or last-of-type, it also works here).

Thus:

tbody tr:nth-child(3n+1):not(:last-child) td {
    text-shadow: red 0 0 8px
}

Final

The final source is:

table {
    display: table;
    font: 90%/1.5em "Lucida Grande", Geneva,
                    "DejaVu Sans", "Bitstream Vera Sans", AnjaliOldLipi,
                    "Lucida sans", "Trebuchet MS", Arial, Verdana;
    text-align: center;
    border: 4px black double;
    border-spacing: 0;
    -moz-border-radius: 12px;
    -moz-box-shadow: #6a3d37 5px 5px 6px;
    -webkit-border-radius: 12px;
    -webkit-box-shadow: #6a3d37 5px 5px 6px;
    border-radius: 12px;
    box-shadow: #6a3d37 5px 5px 6px;
    background: #b59d5c
}

th {
    color: #fff;
    font-size: 110%;
    text-shadow: #6a3d37 2px 2px 2px
}

    th:first-of-type {
        font-weight: bold;
        font-style: italic
    }

tbody tr:nth-child(odd) {
    color: #e0d8cb;
    background: #474644
}

tbody tr:nth-child(even) {
    color: #6a3d37
}

th:first-of-type,
td:first-of-type {
    padding: 0 0 0 4em
}

th:last-of-type,
td:last-of-type {
    padding: 0 4em 0 0
}

tbody tr:nth-last-child(-n+2) {
    opacity: .75
}

tbody tr:nth-child(3n+1):not(:last-child) td {
    text-shadow: red 0 0 8px
}

Author

Created by Ivan Enderlin, Hoa project, june 2009.