MaterializeのCard周りのクラス名について

# 動機

Drupalで作るつもりだったサイトをペライチで作ることになったので、デザイン諸々をMaterializeで実装することにした。
しかしこの公式ドキュメント、肝心なクラス名の説明などが全くなされていないので、自力でCSSとJSから解読することにした。
[Documentation - Materialize](http://materializecss.com/)

# 概要

下記ページで紹介されている、Cardコンポーネント周りのクラス名について調査する。
[Cards - Materialize](http://materializecss.com/cards.html)

# 一般的なCard

以下は、一般的なCardコンポーネントのコードを上で挙げたドキュメントから抜粋したものである。

```html
<div class="container">
    <div class="row">
        <div class="col s12 m7">
            <div class="card">
                <div class="card-image">
                    <img src="images/sample-1.jpg">
                    <span class="card-title">Card Title</span>
                </div>
                <div class="card-content">
                    <p>I am a very simple card. I am good at containing small bits of information.
                       I am convenient because I require little markup to use effectively.</p>
                </div>
                <div class="card-action">
                    <a href="#">This is a link</a>
                </div>
            </div>
        </div>
    </div>
</div>
```

![01.png](https://qiita-image-store.s3.amazonaws.com/0/95607/774e46b3-989b-2873-6e05-2e1648c5c3d9.png)


## `.container`

`.container`単体がやっていることは以下の通り。

```css
.container {
  margin: 0 auto;
  max-width: 1280px;
  width: 90%;
}

@media only screen and (min-width: 601px) {
  .container {
    width: 85%;
  }
}

@media only screen and (min-width: 993px) {
  .container {
    width: 70%;
  }
}
```
(以上、materialize.cssより6649～6665行目を抜粋）

ポイントとしては、`max-width`が1280pxに指定されているので、画面いっぱいに背景画像を配置する場合などは、幅をそれに合わせればいいというところか。

## `.row`

`.row`は基本的に`.container`の中で使うことが前提とされているらしい。

```css
.container .row {
  margin-left: -0.75rem;
  margin-right: -0.75rem;
}
```
```css
.row {
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 20px;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}
```
(以上、materialize.cssより6667～6670行目、6689～6699行目を抜粋）

ポイントとしては、`.row`で区切ったエレメントは`float`を使おうが`inline-block`化しようが、きちんとリセットされるということ。

## `.col`

`.col`は基本的に`.row`の中で使う。ここから一気に話がややこしくなる。

```css
.row .col {
  float: left;
  box-sizing: border-box;
  padding: 0 0.75rem;
}
```
(以上、materialize.cssより6701～6705行目を抜粋）

これだけだとただのfloatBOXだが、ここに`.sN`と`.mM`というオプションがつくことでサイズをあれそれできるようになる。

### `.col.sN`

`.col`と`.sN`(N:1～12)を組み合わせることによって、**floatBOXの幅を規定することができる**。

```css
.row .col.s1 {
  width: 8.3333333333%;
  margin-left: auto;
  left: auto;
  right: auto;
}
/* ------ 中略 ------ */
.row .col.s12 {
  width: 100%;
  margin-left: auto;
  left: auto;
  right: auto;
}
```
(以上、materialize.cssより6711～6793行目を部分抜粋）
実際の指定値をまとめると下表のようになる。

|sN|width|
|:-:|:---:|
|s1|8.3333333333%|
|s2|16.6666666667%|
|s3|25%|
|s4|33.3333333333%|
|s5|41.6666666667%|
|s6|50%|
|s7|58.3333333333%|
|s8|66.6666666667%|
|s9|75%|
|s10|83.3333333333%|
|s11|91.6666666667%|
|s12|100%|

だいたい**width.value ≒ 8 × N**だと思っておけばいいのかもしれない。

### `.col.mM`

では`.mM`は何をやっているかというと、こちらもfloatBOXのサイズを調整している。
~~ただし、機能するのはデバイス幅が小さい場合のみで、完全にレスポンシブデザイン用の機能といえる。~~
2016/03/24 21:07追記
デバイス幅じゃない、メディア幅だ！メディア幅が一定値を下回っていると`.mM`が機能します！！！
指定値も`.sN`系と全く同じである。

## `.card`

`.card`系のクラスに関する記述は、materialize.cssの7747行目以降に存在する。

```css
.card {
  position: relative;
  margin: 0.5rem 0 1rem 0;
  background-color: #fff;
  transition: box-shadow .25s;
  border-radius: 2px;
}
```
(以上、materialize.cssより7755～7761行目を抜粋）

`.card`を使えば勝手に適切なボックスシャドウをつけてくれる。便利。

### `.small`、`.medium`、`.large`との組み合わせ

`.small`、`.medium`、`.large`、これらのclassはCardの高さを規定する。

```css
.card.small {
  height: 300px;
}

.card.medium {
  height: 400px;
}

.card.large {
  height: 500px;
}
```
(以上、materialize.cssより7795～7805行目を抜粋）
一応まとめておくと、下表のようになる。

|class|height|
|:-:|:---:|
|small|300px|
|medium|400px|
|large|500px|

ただ、これらの3つのオプションは`.card-image`を使うことを前提としているところがある。
以下の記述の通り、**画像表示域：コンテンツ表示域 = 60：40**になるように調節しているからだ。

```css
.card.small .card-image, .card.medium .card-image, .card.large .card-image {
  max-height: 60%;
  overflow: hidden;
}

.card.small .card-content, .card.medium .card-content, .card.large .card-content {
  max-height: 40%;
  overflow: hidden;
}
```
(以上、materialize.cssより7776～7784行目を抜粋）

よって、イメージを用いないCardでは直接高さを指定するのも十分ありだと感じた。

## `.card-image`

```css
.card .card-image {
  position: relative;
}

.card .card-image img {
  display: block;
  border-radius: 2px 2px 0 0;
  position: relative;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}
```
(以上、materialize.cssより7807～7820行目を抜粋）

ポイントは気をきかせて小さめの画像を用意しても、親要素で幅指定(`.sN`)を間違えていたら思いっきり引き伸ばされて表示されてしまうこと。

## `.card-content`

```css
.card .card-content {
  padding: 20px;
  border-radius: 0 0 2px 2px;
}

.card .card-content p {
  margin: 0;
  color: inherit;
}
```
(以上、materialize.cssより7830～7838行目を抜粋）

## `.card-title`

`.card-title`は`.card-image`内に置いたときと、`.card-content`内に置いたときで挙動が違う。

```css
.card .card-image .card-title {
  color: #fff;
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 20px;
}
```
(以上、materialize.cssより7822～7828行目を抜粋）

```css
.card .card-content .card-title {
  line-height: 48px;
}
```
(以上、materialize.cssより7840～7842行目を抜粋）

具体的な違いは、`.card-image`内に置くと**左下に白い文字で表示される**ということだ。

# 改めて最初のコードを見てみる

```html
<div class="container"> <!-- 幅とmargin指定する -->
    <div class="row"> <!-- 行を作る -->
        <div class="col s12 m7"> <!-- 幅いっぱい使う -->
            <div class="card"> <!-- Cardコンポーネントを使う -->
                <div class="card-image"> <!-- イメージをセットする -->/
                    <img src="images/sample-1.jpg">
                    <span class="card-title">Card Title</span> <!-- イメージ右下に白字で記述する -->
                </div>
                <div class="card-content"> <!-- 本文を記述する -->
                    <p>I am a very simple card. I am good at containing small bits of information.
                       I am convenient because I require little markup to use effectively.</p>
                </div>
                <div class="card-action">
                    <a href="#">This is a link</a>
                </div>
            </div>
        </div>
    </div>
</div>
```

今回はここまで。

# 確認ソースバージョン

Materialize v0.97.5 (http://materializecss.com)