【競馬】5代血統表をtableでなくCSS gridで作成する

プログラミング WEB制作系

唐突にWEB制作系の話題に脱線。
競馬についての記事を執筆する際に、話題にあげる馬の5代血統表を図表として貼って説明を行いたくなる事が多い。これまでの記事ではnetkeibaの5代血統表にリンクを貼って別ウィンドウで開いてもらう方式を採っていたが、いちいちこれをやっていると読者にクリックとウィンドウ位置調整の面倒を強いる上に場合によってはそのままページ離脱されてしまう。そこで、記事内に5代血統表を貼って完結する方式に変えようと試みた。

tableタグを使った血統表作成の問題点

HTML文書で表を作成する場合に推奨されるタグはtableタグである。ただこのtableタグはそれこそウン十年前に仕様が策定された化石のようなタグであり、たとえば以下のような5代血統表を作ろうと思ったとき、

父 父父 父父父 父父父父 父父父父父
父父父父母
父父父母 父父父母父
父父父母母
父父母 父父母父 父父母父父
父父母父母
父父母母 父父母母父
父父母母母
父母 父母父 父母父父 父母父父父
父母父父母
父母父母 父母父母父
父母父母母
父母母 父母母父 父母母父父
父母母父母
父母母母 父母母母父
父母母母母
母 母父 母父父 母父父父 母父父父父
母父父父母
母父父母 母父父母父
母父父母母
母父母 母父母父 母父母父父
母父母父母
母父母母 母父母母父
母父母母母
母母 母母父 母母父父 母母父父父
母母父父母
母母父母 母母父母父
母母父母母
母母母 母母母父 母母母父父
母母母父母
母母母母 母母母母父
母母母母母

tableタグを使ったコードでは以下のようになる。

<table>
<tr><td rowspan="16">父</td><td rowspan="8">父父</td><td rowspan="4">父父父</td><td rowspan="2">父父父父</td><td>父父父父父</td></tr>
<tr><td>父父父父母</td></tr>
<tr><td rowspan="2">父父父母</td><td>父父父母父</td></tr>
<tr><td>父父父母母</td></tr>
<tr><td rowspan="4">父父母</td><td rowspan="2">父父母父</td><td>父父母父父</td></tr>
<tr><td>父父母父母</td></tr>
<tr><td rowspan="2">父父母母</td><td>父父母母父</td></tr>
<tr><td>父父母母母</td></tr>
<tr><td rowspan="8">父母</td><td rowspan="4">父母父</td><td rowspan="2">父母父父</td><td>父母父父父</td></tr>
<tr><td>父母父父母</td></tr>
<tr><td rowspan="2">父母父母</td><td>父母父母父</td></tr>
<tr><td>父母父母母</td></tr>
<tr><td rowspan="4">父母母</td><td rowspan="2">父母母父</td><td>父母母父父</td></tr>
<tr><td>父母母父母</td></tr>
<tr><td rowspan="2">父母母母</td><td>父母母母父</td></tr>
<tr><td>父母母母母</td></tr>
<tr><td rowspan="16">母</td><td rowspan="8">母父</td><td rowspan="4">母父父</td><td rowspan="2">母父父父</td><td>母父父父父</td></tr>
<tr><td>母父父父母</td></tr>
<tr><td rowspan="2">母父父母</td><td>母父父母父</td></tr>
<tr><td>母父父母母</td></tr>
<tr><td rowspan="4">母父母</td><td rowspan="2">母父母父</td><td>母父母父父</td></tr>
<tr><td>母父母父母</td></tr>
<tr><td rowspan="2">母父母母</td><td>母父母母父</td></tr>
<tr><td>母父母母母</td></tr>
<tr><td rowspan="8">母母</td><td rowspan="4">母母父</td><td rowspan="2">母母父父</td><td>母母父父父</td></tr>
<tr><td>母母父父母</td></tr>
<tr><td rowspan="2">母母父母</td><td>母母父母父</td></tr>
<tr><td>母母父母母</td></tr>
<tr><td rowspan="4">母母母</td><td rowspan="2">母母母父</td><td>母母母父父</td></tr>
<tr><td>母母母父母</td></tr>
<tr><td rowspan="2">母母母母</td><td>母母母母父</td></tr>
<tr><td>母母母母母</td></tr>
</table>

trタグやtdタグを取り除いてボックス内のテキストだけを抽出するならば、”父“→”父父“→”父父父“→”父父父父“→”父父父父父“ここまではまあまあ直感的な順番になるのだが、その後が”父父父父母“→”父父父母父“→”父父父母母“→”父父母“→”父父母父“→”父父母父父“…とおよそ直感的でない順番で馬名を並べていかないといけない。コードを書く側としては(表の見た目を実現するためだけに)この直感的でない順番を意識して書かないといけないし、閲覧者の側がじゃあこの血統情報を何かに再活用しよう、と思いコピペをしてもバラバラに並んだ馬名しか取得できない。もうちょっとスマートなコードを目指したい。

CSS gridを使えばビューに関する部分をHTMLから完全に分離できそう

今回tableタグを使わずに代わりに使いたいのはリストを表すulタグ。tableタグを使うことで「ソースコードのこの部分は同じ表に含まれる関連性のあるテキストですよ」という情報が検索エンジンのクローラー等に伝わるわけだが、似たようなことはリストを表すタグでも出来そうだと思ったからだ(少なくとも平の文で馬の名前を羅列していくよりは良い)。
表っぽい見た目にするにはulタグに適用されるCSSを書けば良いのだが、昔のCSSでそれをやろうとするとfloat使ったりflexbox使ったりで結構面倒臭い技が必要だった。一方最近はどうやらCSS gridという仕組みが実装されたらしく、レイアウトもflexboxよりも柔軟でこれなら痒いところに手が届きそうだ。注意点として最近追加されたCSSであるから昔のブラウザではうまく表示されない。IEないし2016年以前のiOS Safariがおおよその境界線になるようだ。

実際に出来たものとソースコード

そんなこんなで完成したのが下の表。

  • 父
  • 母
  • 父父
  • 父母
  • 母父
  • 母母
  • 父父父
  • 父父母
  • 父母父
  • 父母母
  • 母父父
  • 母父母
  • 母母父
  • 母母母
  • 父父父父
  • 父父父母
  • 父父母父
  • 父父母母
  • 父母父父
  • 父母父母
  • 父母母父
  • 父母母母
  • 母父父父
  • 母父父母
  • 母父母父
  • 母父母母
  • 母母父父
  • 母母父母
  • 母母母父
  • 母母母母
  • 父父父父父
  • 父父父父母
  • 父父父母父
  • 父父父母母
  • 父父母父父
  • 父父母父母
  • 父父母母父
  • 父父母母母
  • 父母父父父
  • 父母父父母
  • 父母父母父
  • 父母父母母
  • 父母母父父
  • 父母母父母
  • 父母母母父
  • 父母母母母
  • 母父父父父
  • 母父父父母
  • 母父父母父
  • 母父父母母
  • 母父母父父
  • 母父母父母
  • 母父母母父
  • 母父母母母
  • 母母父父父
  • 母母父父母
  • 母母父母父
  • 母母父母母
  • 母母母父父
  • 母母母父母
  • 母母母母父
  • 母母母母母

HTML側のソースは以下のとおり。

<ul class="godai_blood_table">
<li>父</li>
<li>母</li>
<li>父父</li>
<li>父母</li>
<li>母父</li>
<li>母母</li>
<li>父父父</li>
<li>父父母</li>
<li>父母父</li>
<li>父母母</li>
<li>母父父</li>
<li>母父母</li>
<li>母母父</li>
<li>母母母</li>
<li>父父父父</li>
<li>父父父母</li>
<li>父父母父</li>
<li>父父母母</li>
<li>父母父父</li>
<li>父母父母</li>
<li>父母母父</li>
<li>父母母母</li>
<li>母父父父</li>
<li>母父父母</li>
<li>母父母父</li>
<li>母父母母</li>
<li>母母父父</li>
<li>母母父母</li>
<li>母母母父</li>
<li>母母母母</li>
<li>父父父父父</li>
<li>父父父父母</li>
<li>父父父母父</li>
<li>父父父母母</li>
<li>父父母父父</li>
<li>父父母父母</li>
<li>父父母母父</li>
<li>父父母母母</li>
<li>父母父父父</li>
<li>父母父父母</li>
<li>父母父母父</li>
<li>父母父母母</li>
<li>父母母父父</li>
<li>父母母父母</li>
<li>父母母母父</li>
<li>父母母母母</li>
<li>母父父父父</li>
<li>母父父父母</li>
<li>母父父母父</li>
<li>母父父母母</li>
<li>母父母父父</li>
<li>母父母父母</li>
<li>母父母母父</li>
<li>母父母母母</li>
<li>母母父父父</li>
<li>母母父父母</li>
<li>母母父母父</li>
<li>母母父母母</li>
<li>母母母父父</li>
<li>母母母父母</li>
<li>母母母母父</li>
<li>母母母母母</li>
</ul>

すっきりしていて格段にわかりやすい。tableタグを使う方法では2行分以上の大きさのセルにはtdタグの属性としてrowspanとかいうサイズを表す数字を入れなければならなかった。HTMLの側にそういうビューに関する記述が残っていることが気持ち悪かったのだが、今回完全に分離することができた。ソースを見るともはやただの箇条書きリストにしか見えないものね。
そして馬名を記述する順番も、”父“→”母“→”父父“→”父母“→”母父“→”母母“→”父父父“→”父父母“→”父母父“→”父母母“…といったように表の位置で言えば左上を起点として縦に潰していっている。n代前の馬の世代を縦に総潰ししたら次はn+1代前の世代を縦に、といった順番である。
この記述法では奇数番目の馬名が牡馬、偶数番目が牝馬となるため、牡馬と牝馬でセルの色を色分けすることも簡単だ。まあともかく。CSSの方も見てみるとするか。

.godai_blood_table{
display:grid; //CSS gridを適用
list-style-type:none; //ulタグのデフォルトである項目の横の"・"をクリア
grid-auto-flow:column; //グリッドを縦方向に埋めていく指定
grid-template-rows:repeat(32,auto); //最大32行のグリッド
}
 
.godai_blood_table li{
border: 1px solid #333; //各セルを囲むボーダー指定 ※ここはお好みで
margin: 0.2em; //各セル間のマージン指定 ※ここはお好みで
}
 
.godai_blood_table li:nth-child(-n+2){
grid-row: span 16; //子要素2番目までは16行分の大きさ
}
 
.godai_blood_table li:nth-child(n+3):nth-child(-n+6){
grid-row: span 8; //子要素3〜6番目までは8行分の大きさ
}
 
.godai_blood_table li:nth-child(n+7):nth-child(-n+14){
grid-row: span 4; //子要素7〜14番目までは4行分の大きさ
}
 
.godai_blood_table li:nth-child(n+15):nth-child(-n+30){
grid-row: span 2; //子要素15〜30番目までは2行分の大きさ
}
 
.godai_blood_table li:nth-child(odd){
background-color: #e6e6fa; //奇数番目の子要素(=牡馬)の色を水色に
}
 
.godai_blood_table li:nth-child(even){
background-color: #ffe4e1; //偶数番目の子要素(=牝馬)の色をピンク色に
}

CSSだけでなかなか柔軟な事が出来る時代になったものだ。
なお今回の血統表用CSSは5代血統表を念頭に置いて書いているのだけれども、たとえばulリストの中の馬名が14頭の3代血統表にこのCSSを適用するとどうなるかというと、それもちゃんと表示してくれた。しかも一番右列のセルはCSSで4行分の大きさと定義しているのにも関わらず1行分の見た目となり、全体では縦8行分のサイズの表になった。そういう仕様ならば10代血統表くらいまで対応できるようアップグレードしておくのも良いかもしれない。

コメント

タイトルとURLをコピーしました