CSS3のセレクターで作るストライプテーブル

隔行、隔列で異なる背景色を持たせるテーブル(ストライプテーブル)を作ってみる回。
ストライプテーブルを作る場合、CSS2の機能だけでは苦労していたらしいが、CSS3の機能を使うとすんごい簡単にできるそうな。
過去のエントリで試行錯誤してそれっぽいの作ってみたけど、今回のエントリでストライプテーブルの王道が理解できるのはありがたい。

まずはjQueryを使用せず、CSS3だけでストライプテーブルを作るとどういうコードになるか。

<html>
  <head>
    <style>
table{
    margin:100px auto;
}
tr:nth-child(even){
    background:lightblue;
}
th{
    background:#222222;
    color:white;
}
th:nth-child(odd){
    background:pink;
}
th,td{
    padding:5px;
    font-size:small;
}
    </style>
  </head>
  <body>
    <table>
      <tr>
        <th>no</th>
        <th>Name</th>
        <th>Birthday</th>
        <th>Phone</th>
        <th>Mail</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Yamada Tarou</td>
        <td>1977-07-25</td>
        <td>090-1234-5678</td>
        <td>example0@to-r.net</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Yamada Hanako</td>
        <td>1979-07-27</td>
        <td>090-1234-5678</td>
        <td>example1@to-r.net</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Tnaka Jiro</td>
        <td>1975-11-05</td>
        <td>090-9999-7777</td>
        <td>example@to-r.net</td>
      </tr>
    </table>
  </body>
</html>

「:nth-child(even)」フィルタと、「:nth-child(odd)」フィルタを使って交互の背景色を指定してる感じ。
Firefoxだと意図したとおりに表示されるが、IE6だとダメらしい。IE8でもダメらしいけど。試せる環境がないから試さないけど、もし誰か試したら教えてください。
ちなみにIE系の場合、隔行、隔列毎に別のクラスを指定してやらないと実現できないそうだ。面倒くさいからコードは記載しませんよ。


さて、では同じことをjQueryでやると?

<html>
  <head>
    <style>
/* styleタグ内ではCSS3を使用していない。 */
table{
    margin:100px auto;
}
.odd{
    background:#444444;
}
th{
    background:#222222;
    color:white;
}
th,td{
    padding:5px;
    font-size:small;
}
.even{
    background:#F2F2F2;
}
    </style>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
    $(function(){
       //セレクター使って該当行、該当列を取得して、スタイルを適用している感じ。
       $("th:nth-child(odd)").addClass("odd");
       $("tr:nth-child(even)").addClass("even");
       //セレクターに直接CSSを指定してもできるが、
       //モジュール化の観点からあくまでもクラスのCSSを定義しておいて、
       //ここではそれだけを指定する方がいいよ。
       //ま、今まで俺が作ってきたコードは完全に無視してっけどw
    })
    </script>
  </head>
  <body>
    <table>
      <tr>
        <th>no</th>
        <th>Name</th>
        <th>Birthday</th>
        <th>Phone</th>
        <th>Mail</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Yamada Tarou</td>
        <td>1977-07-25</td>
        <td>090-1234-5678</td>
        <td>example0@to-r.net</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Yamada Hanako</td>
        <td>1979-07-27</td>
        <td>090-1234-5678</td>
        <td>example1@to-r.net</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Tnaka Jiro</td>
        <td>1975-11-05</td>
        <td>090-9999-7777</td>
        <td>example@to-r.net</td>
      </tr>
    </table>
  </body>
</html>

これでIEでも同じように表示されるのかな。


最後に、マウスオーバーした行や列をハイライト(背景色を変更)する方法をご紹介。
まずはHTMLとCSSのみの場合。

<html>
  <head>
    <style>
table{
    margin:100px auto;
}
tr:nth-child(even){
    background:lightblue;
}
th{
    background:#222222;
    color:white;
}
th:nth-child(odd){
    background:pink;
}
th,td{
    padding:5px;
    font-size:small;
}
/* 行をハイライトする為のCSSを追加! */
tr:not(:first-child):hover{
    background:red;
}
    </style>
  </head>
  <body>
    <table>
      <tr>
        <th>no</th>
        <th>Name</th>
        <th>Birthday</th>
        <th>Phone</th>
        <th>Mail</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Yamada Tarou</td>
        <td>1977-07-25</td>
        <td>090-1234-5678</td>
        <td>example0@to-r.net</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Yamada Hanako</td>
        <td>1979-07-27</td>
        <td>090-1234-5678</td>
        <td>example1@to-r.net</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Tnaka Jiro</td>
        <td>1975-11-05</td>
        <td>090-9999-7777</td>
        <td>example@to-r.net</td>
      </tr>
    </table>
  </body>
</html>

で、やはりこれだとIE系では正しく表示されないので、jQueryを使用したパターン。

<html>
  <head>
    <style>
table{
    margin:100px auto;
}
.odd{
    background:lightblue;
}
th{
    background:pink;
    color:white;
}
th,td{
    padding:5px;
    font-size:small;
}
.even{
    background:lightgreen;
}
/* マウスが上に着た時のスタイル */
.hover{
    background:yellow;
}
    </style>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
    $(function(){
       //セレクター使って該当行、該当列を取得して、スタイルを適用している感じ。
       $("th:nth-child(odd)").addClass("odd");
       $("tr:nth-child(even)").addClass("even");
       //以下を追加。
       //マウスオーバー、マウスアウトイベントで、hoverクラスを適用したり外したりする感じ。
       $("tr:not(:first-child)").mouseover(function(){
         $(this).addClass("hover");
       }).mouseout(function(){
         $(this).removeClass("hover");
       })   
     })
    </script>
  </head>
  <body>
    <table>
      <tr>
        <th>no</th>
        <th>Name</th>
        <th>Birthday</th>
        <th>Phone</th>
        <th>Mail</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Yamada Tarou</td>
        <td>1977-07-25</td>
        <td>090-1234-5678</td>
        <td>example0@to-r.net</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Yamada Hanako</td>
        <td>1979-07-27</td>
        <td>090-1234-5678</td>
        <td>example1@to-r.net</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Tnaka Jiro</td>
        <td>1975-11-05</td>
        <td>090-9999-7777</td>
        <td>example@to-r.net</td>
      </tr>
    </table>
  </body>
</html>

これでいける感じ。


続いて列のハイライト。行のハイライトは比較的簡単だが、列のハイライトは一発でまとめて選択できるセレクターが無いのでちょっと面倒。
一応考え方をコード内にコメントとして記述してみた。

<html>
  <head>
    <style>
table{
    margin:100px auto;
}
.odd{
    background:lightblue;
}
th{
    background:pink;
    color:white;
}
th,td{
    padding:5px;
    font-size:small;
}
.even{
    background:lightgreen;
}
/* マウスが上に着た時のスタイル */
.hover{
    background:yellow;
}
    </style>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.3.2");</script>
    <script type="text/javascript">
    $(function(){
       $("th:nth-child(odd)").addClass("odd");
       $("tr:nth-child(even)").addClass("even");
       $("tr:not(:first-child)").mouseover(function(){
         $(this).addClass("hover");
       }).mouseout(function(){
         $(this).removeClass("hover");
       })

       /* 列のハイライト */
       $("td").mouseover(function(){
         //tableの中に出現するtd要素のインデックスを取得する。
         var index = $("td").index(this);
         //th要素のサイズを取得する。
         var size = $("th").size();
         //各行の先頭から何番目かを取得
         var order = index % size + 1;
         $("td:nth-child("+ order + ")").addClass("hover");
       }).mouseout(function(){
         //tableの中に出現するtd要素のインデックスを取得する。
         var index = $("td").index(this);
         //th要素のサイズを取得する。
         var size = $("th").size();
         //各行の先頭から何番目かを取得
         var order = index % size + 1;
         $("td:nth-child("+ order + ")").removeClass("hover");
       })
     })
    </script>
  </head>
  <body>
    <table>
      <tr>
        <th>no</th>
        <th>Name</th>
        <th>Birthday</th>
        <th>Phone</th>
        <th>Mail</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Yamada Tarou</td>
        <td>1977-07-25</td>
        <td>090-1234-5678</td>
        <td>example0@to-r.net</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Yamada Hanako</td>
        <td>1979-07-27</td>
        <td>090-1234-5678</td>
        <td>example1@to-r.net</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Tnaka Jiro</td>
        <td>1975-11-05</td>
        <td>090-9999-7777</td>
        <td>example@to-r.net</td>
      </tr>
    </table>
  </body>
</html>

ちなみにtd要素については次のようにindexが降られていることを把握しておこう。

no Name Birthday Phone Mail
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
これで列のハイライトもできちゃう感じ。