Grid Layoutで競馬のサービスが作りやすくなりそう！

この記事は、[株式会社Y's アドベントカレンダー](https://qiita.com/advent-calendar/2017/ysinc) 16日目の記事になります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/157683/6787fa76-fa0c-6e52-0721-74528b44c06a.jpeg" width="100%">

#競馬とは

競馬とは、日本中央競馬会(JRA)・地方競馬全国協会(NAR)が主催している、競走馬のレースのことです。
賞金が高いG1レースですと「天皇賞」「ダービー」「エリザベス女王杯」「有馬記念」などが有名です。

天皇賞：	1着15000万円 2着6000万円 3着3800万円 4着2300万円 5着1500万円
ダービー：1着20000万円 2着8000万円 3着5000万円 4着3000万円 5着2000万円
エリザベス女王杯：1着9300万円 2着3700万円 3着2300万円 4着1400万円 5着930万円
有馬記念：1着30000万円 2着12000万円 3着7500万円 4着4500万円 5着3000万円	

#競馬は血統のスポーツである
競走馬といえばサラブレッドのことを指します。
サラブレッドの歴史は、300年前のイギリスから始まります。
サラブレッドは、優秀な競争成績を残した馬が、種牡馬(オス)や繁殖牝馬(メス)として子孫を残すことで、何世代にもわたって品種改良が続けられている品種です。

#血統表とは

馬の祖先を表にまとめたものです。
左から右へ祖先を記述してきます。

<table>
<tr><th rowspan="4">父</th><th rowspan="2">父父</th><th>父父父</th></tr>
<tr><th>父父母</th></tr>
<tr><th rowspan="2">父母</th><th>父母父</th></tr>
<tr><th>父母母</th></tr>
<tr><th rowspan="4">母</th><th rowspan="2">母父</th><th>母父父</th></tr>
<tr><th>母父母</th></tr>
<tr><th rowspan="2">母母</th><th>母母父</th></tr>
<tr><th>母母母</th></tr>
</table>

昔は、サラブレッド以外の品種(在来種やアラブ種)とも交配していたため、雑種なのかサラブレッドなのか曖昧な馬もおりました。
そこで、サラブレッドとして認める基準が必要となりました。

そこで現在は、
・8代連続でサラブレッドと交配していること(馬は4歳で大人になる)
・国際血統書委員会よりサラブレッドと同等の能力を有すると認められること
というのがサラブレッドの基準となっています。

#Grid Layoutがやってきた
今年の3月のタイミングで、各種ブラウザが一斉にバージョンアップしました。
その結果、ようやく「Grid Layout」の対応が出そろいました。

https://caniuse.com/#search=CSS%20Grid%20Layout

![CSS Grid Layout.png](https://qiita-image-store.s3.amazonaws.com/0/157683/4cbdc298-0ecb-ae47-f9f0-22b432e10be8.png)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/tPBl1J0VVB">https://t.co/tPBl1J0VVB</a></p>&mdash; s.hayashi (@shayashi3) <a href="https://twitter.com/shayashi3/status/942204710978600963?ref_src=twsrc%5Etfw">2017年12月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#Grid Layoutの何が画期的なのか？

それは、血統表がめちゃくちゃ作りやすくなりました！

具体的には、どのように作りやすくなったのか？
詳細は以下の通りです。

#今までの血統表の作り方

今までは、親子関係を無視した「trタグ」と「rowspan」の組み合わせで、必死にセルの結合を表現しておりました。
HTMLを良く見ると「一定の法則」を見出すことはできますが、それを毎回覚えるのは大変でした。

イメージするならば、高さの違うセルをもった行を、何層も積み重ねていくイメージです。
もし「rowspan」や「積み重ねる順番」を間違えると、親子関係がぐちゃぐちゃの血統表ができあがります。

```html:HTML
<table>
    <!-- 父系 -->
    <tr>
        <td rowspan="16" class="m">父</td>
        <td rowspan="8" class="m">父父</td>
        <td rowspan="4" class="m">父父父</td>
        <td rowspan="2" class="m">父父父父</td>
        <td rowspan="1" class="m">父父父父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父父父父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">父父父母</td>
        <td rowspan="1" class="m">父父父母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父父父母母</td>
    </tr>
    <tr>
        <td rowspan="4" class="f">父父母</td>
        <td rowspan="2" class="m">父父母父</td>
        <td rowspan="1" class="m">父父母父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父父母父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">父父母母</td>
        <td rowspan="1" class="m">父父母母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父父母母母</td>
    </tr>
    <tr>
        <td rowspan="8" class="f">父母</td>
        <td rowspan="4" class="m">父母父</td>
        <td rowspan="2" class="m">父母父父</td>
        <td rowspan="1" class="m">父母父父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父母父父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">父母父母</td>
        <td rowspan="1" class="m">父母父母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父母父母母</td>
    </tr>
    <tr>
        <td rowspan="4" class="f">父母母</td>
        <td rowspan="2" class="m">父母母父</td>
        <td rowspan="1" class="m">父母母父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父母母父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">父母母母</td>
        <td rowspan="1" class="m">父母母母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">父母母母母</td>
    </tr>
    
    <!-- 母系 -->
    <tr>
        <td rowspan="16" class="f">母</td>
        <td rowspan="8" class="m">母父</td>
        <td rowspan="4" class="m">母父父</td>
        <td rowspan="2" class="m">母父父父</td>
        <td rowspan="1" class="m">母父父父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母父父父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">母父父母</td>
        <td rowspan="1" class="m">母父父母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母父父母母</td>
    </tr>
    <tr>
        <td rowspan="4" class="f">母父母</td>
        <td rowspan="2" class="m">母父母父</td>
        <td rowspan="1" class="m">母父母父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母父母父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">母父母母</td>
        <td rowspan="1" class="m">母父母母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母父母母母</td>
    </tr>
    <tr>
        <td rowspan="8" class="f">母母</td>
        <td rowspan="4" class="m">母母父</td>
        <td rowspan="2" class="m">母母父父</td>
        <td rowspan="1" class="m">母母父父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母母父父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">母母父母</td>
        <td rowspan="1" class="m">母母父母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母母父母母</td>
    </tr>
    <tr>
        <td rowspan="4" class="f">母母母</td>
        <td rowspan="2" class="m">母母母父</td>
        <td rowspan="1" class="m">母母母父父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母母母父母</td>
    </tr>
    <tr>
        <td rowspan="2" class="f">母母母母</td>
        <td rowspan="1" class="m">母母母母父</td>
    </tr>
    <tr>
        <td rowspan="1" class="f">母母母母母</td>
    </tr>          
</table>
```

```css:CSS
* {
    margin: 0;
    padding: 0;
}

body {
    font-size: 12px;
}

table {
    border-collapse: collapse;
    width: 100%;
}

td {
    border: solid 2px #333333;
    width: 20%;
    text-align: center;
    vertical-align: middle;
}

.m {
    background: #88ff88;
}

.f {
    background: #ff8888;
}
```

[実行サンプル](https://codepen.io/satoshi_hayashi/pen/wpKQMZ "今までの血統表作り方")

#これからの血統表作り方

Grid Layoutによって、セルの結合を表現しやすくなりました。

■やり方
1.Gridに「grid-template-rows」と「grid-template-columns」を設定して、任意の行数・列数に分割しておきます。

```css:CSS
.container {
    display: grid;
    grid-template-rows: repeat(32, 20px); /* 2の5乗で32 */
    grid-template-columns: repeat(5, 20%);
    border: solid 1px #333333;
}
```

2.各セルに「grid-column」と「grid-row」を設定して、「どの位置に」「どのサイズ」で配置するのかを指定します。

```css:CSS
/* 両親 */
.g1 {
    grid-column: 1;
    grid-row: span 16;
}

/* 祖父母 */
.g2 {
    grid-column: 2;
    grid-row: span 8;
}

/* 曽祖父母 */
.g3 {
    grid-column: 3;
    grid-row: span 4;
}

/* 高祖父母 */
.g4 {
    grid-column: 4;
    grid-row: span 2;
}

/* 五世祖父母 */
.g5 {
    grid-column: 5;
    grid-row: span 1;
}
```

これで、親子関係を維持した分かりやすいHTMLで書くことができます。
・右にインデントが進むごとに、祖先に戻る
・左にインデントが進むごとに、子孫に進む

エンジニアの方ならば、
親子関係が崩れている「今までの作り方」よりも、
親子関係が維持された「これからの作り方」の方が、
PHPやJavaScriptでプログラムしやすいのは、何となく理解いただけるかと思っております。

```html:HTML
<div class="container">
    <!-- 父系 -->
    <div class="g1 m">父</div>
        <div class="g2 m">父父</div>
            <div class="g3 m">父父父</div>
                <div class="g4 m">父父父父</div>
                    <div class="g5 m">父父父父父</div>
                    <div class="g5 f">父父父父母</div>
                <div class="g4 f">父父父母</div>
                    <div class="g5 m">父父父母父</div>
                    <div class="g5 f">父父父母母</div>
            <div class="g3 f">父父母</div>
                <div class="g4 m">父父母父</div>
                    <div class="g5 m">父父母父父</div>
                    <div class="g5 f">父父母父母</div>
                <div class="g4 f">父父母母</div> 
                    <div class="g5 m">父父母母父</div>
                    <div class="g5 f">父父母母母</div>
        <div class="g2 f">父母</div>
            <div class="g3 m">父母父</div>
                <div class="g4 m">父母父父</div>
                    <div class="g5 m">父母父父父</div>
                    <div class="g5 f">父母父父母</div>
                <div class="g4 f">父母父母</div>
                    <div class="g5 m">父母父母父</div>
                    <div class="g5 f">父母父母母</div>
            <div class="g3 f">父母母</div>
                <div class="g4 m">父母母父</div>
                    <div class="g5 m">父母母父父</div>
                    <div class="g5 f">父母母父母</div>
                <div class="g4 f">父母母母</div> 
                    <div class="g5 m">父母母母父</div>
                    <div class="g5 f">父母母母母</div>
    <!-- 母系 -->    
    <div class="g1 f">母</div>
        <div class="g2 m">母父</div>
            <div class="g3 m">母父父</div>
                <div class="g4 m">母父父父</div>
                    <div class="g5 m">母父父父父</div>
                    <div class="g5 f">母父父父母</div>
                <div class="g4 f">母父父母</div>
                    <div class="g5 m">母父父母父</div>
                    <div class="g5 f">母父父母母</div>
            <div class="g3 f">母父母</div>
                <div class="g4 m">母父母父</div>
                    <div class="g5 m">母父母父父</div>
                    <div class="g5 f">母父母父母</div>
                <div class="g4 f">母父母母</div> 
                    <div class="g5 m">母父母母父</div>
                    <div class="g5 f">母父母母母</div>
        <div class="g2 f">母母</div>
            <div class="g3 m">母母父</div>
                <div class="g4 m">母母父父</div>
                    <div class="g5 m">母母父父父</div>
                    <div class="g5 f">母母父父母</div>
                <div class="g4 f">母母父母</div>
                    <div class="g5 m">母母父母父</div>
                    <div class="g5 f">母母父母母</div>
            <div class="g3 f">母母母</div>
                <div class="g4 m">母母母父</div>
                    <div class="g5 m">母母母父父</div>
                    <div class="g5 f">母母母父母</div>
                <div class="g4 f">母母母母</div> 
                    <div class="g5 m">母母母母父</div>
                    <div class="g5 f">母母母母母</div>
</div>
```

CSSの全体は以下になります。

```css:CSS
* {
    margin: 0;
    padding: 0;
}

body {
    font-size: 12px;
}

.container {
    display: grid;
    grid-template-rows: repeat(32, 20px); /* 2の5乗で32 */
    grid-template-columns: repeat(5, 20%);
    border: solid 1px #333333;
}

.container div {
    border: solid 1px #333333;
    display: flex;
    justify-content: center;
    align-items: center;
}

.m {
    background: #88ff88;
}

.f {
    background: #ff8888;
}

/* 両親 */
.g1 {
    grid-column: 1;
    grid-row: span 16;
}

/* 祖父母 */
.g2 {
    grid-column: 2;
    grid-row: span 8;
}

/* 曽祖父母 */
.g3 {
    grid-column: 3;
    grid-row: span 4;
}

/* 高祖父母 */
.g4 {
    grid-column: 4;
    grid-row: span 2;
}

/* 五世祖父母 */
.g5 {
    grid-column: 5;
    grid-row: span 1;
}
```

[実行サンプル](https://codepen.io/satoshi_hayashi/pen/zpvMqN "これからの血統表作り方")

#まとめ

今回は「Grid Layout」の活用例について見てきました。
世間では「Grid Layoutでレスポンシブ対応が便利になる」ということで、注目を集めていますが、
「サラブレッドの血統表が作りやすくなる」という、割とニッチな世界をご紹介させていただきました。

#おまけ

おそらく、Web系のフロントエンジニアの方ならば、レスポンシブ対応が便利になる「Grid Layout」の存在は、どこかでキャッチしておられると思います。

しかし今回は、業務系のエンジニアの方にこそ、「Grid Layout」の存在を知っていただきたいと思っています。
なぜなら、日本の帳票は、世界一細かいからです。
例えば、ドキュメントをなんでもExcelで作ったり、Excelを方眼紙代わりにして細かい帳票を作ることも、日本特有の文化です。

そこで「Grid Layout」を活用することで、「作業効率の向上」や「バグ発生率の低下」を図り、業務系のエンジニアの皆さんが、幸せになる未来が来てほしい！と切に願っております。

次は 17日目 @T_igarashi さんの記事です。お楽しみに！!