Outlookに勝てるHTMLメールコーディング vol.2「レスポンシブ設計編」


前回に引き続きメールコーディングのちょっとしたコツをつらつらと書いていきたいと思います。
ちなみに前回の投稿はこちらから。
[Outlookに勝てるHTMLメールコーディング vol.1「table構成編」](http://qiita.com/drasky1132/items/7beb80589ae1cef7f5e6)


## あんまり関係ないけどファイル構成

特にレスポンシブ対応には関係ないのですが、HTMLメールのコーディングってとにかくコードが長く、インデントも煩雑になっていきませんか？

今回長文のコードを書くに当たって、ファイル分割してコーディングしています。
共通化できる場所を別ファイルとして作成しておけば、一括でヘッダなどの内容も変えることが出来ますし、何よりコードの可読性があがります。

### 分割したファイル構成

```html
<!-- ヘッダの設定 -->
<%= render :partial => '/user_mailer/template_head' %>


<body class="res" width="100%" bgcolor="#4caf50" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" style="width:100%;background:#4caf50;margin:0;">

  <!-- response対応用 css -->
  <%= render :partial => '/user_mailer/template_css' %>
  
  <!-- (1)ロゴの部分 開始タグ -->
  <%= render :partial => '/user_mailer/template_head_logo' %>
  
    <!-- コンテンツここから -->
    <table width="100%" border="0" cellpadding="0" cellspacing="0" style="width:100%;border:none;margin:0;">
      <tr>
        <td width="100%" bgcolor="#ededed" border="0" cellpadding="0" cellspacing="0" style="width:100%;background:#ededed;border:none;margin:0;">

          <table width="100%" border="0" cellpadding="0" cellspacing="0" style="width:100%;border:none;margin:0;">
            <tr>
              <td width="2%" border="0" cellpadding="0" cellspacing="0" style="width:2%;border:none;margin:0;"></td>
              <td width="96%" border="0" cellpadding="0" cellspacing="0" style="width:96%;border:none;margin:0 auto;">

                <table width="100%" border="0" cellpadding="0" cellspacing="0" style="width:100%;border:none;margin:0;">
                  <tr>
                    <td width="100%" height="16" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:16px;border:none;margin:0;"></td>
                  </tr>
                  <tr>
                    <td width="100%" border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;border:none;margin:0;text-align:left;">
                      <font color="#414141" size="3" style="font-size:14px;color:#414141;">
                        <%= @preface %>
                      </font>
                    </td>
                  </tr>
                  <tr>
                    <td width="100%" height="16" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:16px;border:none;margin:0;"></td>
                  </tr>
                </table>

              </td>
              <td width="2%" border="0" cellpadding="0" cellspacing="0" style="width:2%;border:none;margin:0;"></td>
            </tr>
          </table>

        </td>
      </tr>
      <tr>
        <td width="100%" height="8" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:8px;border:none;margin:0;"></td>
      </tr>
    </table>
    <!-- コンテンツここまで -->

    <!-- 共通コンテンツここから -->
    <%= render :partial => '/user_mailer/template_whitecard_top' %>
    
      <%= render :partial => '/user_mailer/offers', :locals => {:offers => @offers} %>
      <%= render :partial => '/user_mailer/features' %>
      <%= render :partial => '/user_mailer/template_infomation' %>

    <!-- 共通コンテンツここまで -->
    <%= render :partial => '/user_mailer/template_whitecard_btm' %>

  <!-- (1)ロゴの部分 閉じタグ -->
  <%= render :partial => '/user_mailer/template_head_logo_end' %>

  <!-- 40px margin -->
  <table width="100%" border="0" cellpadding="0" cellspacing="0" style="width: 100%;border:none;margin:0;">
    <tr>
      <td width="100%" height="40" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:40px;border:none;margin:0;"></td>
    </tr>
  </table>
  
  <!-- フッター -->
  <%= render :partial => '/user_mailer/template_footer' %>

</body>
</html>

```

## レスポンシブの心得

### レスポンシブ対応するためのbody設定

画面サイズに最適されるようにsize-adjustを入れましょう！

```css
body {
  width: 100% !important;
  min-width: 100%;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  margin: 0;
  padding: 0;
}
```

### あると便利なCSS設定

とりあえずレスポンシブ対応に必要なCSS設定をざっと置いておきます。
コピペで使えます。

```css
<style type="text/css">
  #outlook a {
    padding: 0;
  }

  body{
    width: 100% !important;
    min-width: 100%;
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%;
    margin: 0;
    padding: 0;
  }

  body.outlook p {
    display: inline !important;
  }

  body .px1 {
    table-layout: fixed !important;
    width: 1px !important;
  }

  body .px3x3 {
    table-layout: fixed !important;
    width: 3px !important;
    height: 3px !important;
  }

  body center {
    min-width: 0 !important;
  }

  body .block {
    display: block !important;
  }

  body .w100 {
    width: 100% !important;
  }

  /*  Media Queries */
  @media only screen and (max-width: 680px) {
    body .res-block { // レスポンシブの時だけブロック要素にする
      display: block !important;
    }
    body .disp-none { // レスポンシブの時だけ要素を消す
      display: none !important;
      height: 0 !important;
    }
    body .res-w100 { // レスポンシブの時だけwidth100%にする
      width: 100% !important;
    }
    body[class="res"] .res-hauto { // レスポンシブの時だけheightをautoにする
      height: auto !important;
    }
  }
</style>
```


### widthの指定はパーセント指定だけを使いましょう。

基本的に全てが横に伸びるように設計します。
widthは常に足して100%になるように作ります。
横幅の指定された要素をどうしても入れたいという場合はCSSの中に、` max-width`や` min-width`で指定していきます。

### レスポンシブ対応は全てCSSで操作する

widthが常に100%になるようにテーブルコーディングをしていきますが、これらをレスポンシブ対応していくのは全てCSSになります。
例えば、横2カラムのテーブルを横幅680px以下のデバイスでは1カラムにさせたい…といった場合、基本的には2カラムでコーディングし、後にCSSにて操作していきます。

## 小技いろいろ

### 解像度によって、2カラムを1カラムで表示させる

以下のテーブルは1列に横に4つのセルが並んでいます。
4つのうち、”コンテンツ”という文字が入っているセル2つを1カラムレイアウトにしています。


```html
<table bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="background:#ffffff;border:none;margin:0 auto;">
  <tr>

    <!-- 1段目 -->
    <td width="8" border="0" cellpadding="0" cellspacing="0" style="width:8px;border:none;margin:0 auto;" class="disp-none"></td>
    <td border="0" cellpadding="0" cellspacing="0"  style="border:none;margin:0 auto;" class="res-block">
      <!-- コンテンツ -->
    </td>

    <!-- 2段目 -->
    <td width="8" border="0" cellpadding="0" cellspacing="0" style="width:8px;border:none;margin:0 auto;" class="disp-none"></td>
    <td border="0" cellpadding="0" cellspacing="0"  style="border:none;margin:0 auto;" class="res-block">
      <!-- コンテンツ -->
    </td>

  </tr>
</table>
```

```scss
@media only screen and (max-width: 680px) {
  body .res-block {
    display: block !important;
  }
  body .disp-none {
    display: none !important;
    height: 0 !important;
  }
}
```

横幅を強制的に100%にするセルに` .res-block`もしくは` .disp-none`をつけていきます。
これで、不要なセルは見えなくなり、必要なセルはブロック要素で表示されるようになります。


### テーブルサイズを操る

稀にパーセントに頼らずにサイズ指定したいセルが出てくることがあります。
その場合、tableタグはパーセントを守ってくれない性質があるので、その場合はtable-layoutを固定してからwidthをコントロールします。

以下は左右に1pxの隙間を持つtableの書き方。
（これはレスポンシブに関係なく指定されます。）

```html
<table width="100%" height="1" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:1px;border:none;">
  <tr>
    <td width="1" height="1" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;border:none;" class="px1"></td>
    <td width="*" height="1" bgcolor="#ededed" border="0" cellpadding="0" cellspacing="0" style="width:auto;height:1px;background:#ededed;border:none;"></td>
    <td width="1" height="1" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;border:none;" class="px1"></td>
  </tr>
</table>
```

```css
body{
  width: 100% !important;
  min-width: 100%;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  margin: 0;
  padding: 0;
}
```

また、基本的にwidthはこのサイズで絶対表示させたい場合は、styleの中にだけwidthを書く方法があります。
これはOutlookでも崩れません。

また、文字の前後の余白を上手くコントロールしたい場合は、` height`と` line-height`を上手く組み合わせて対応していきます。

```html
<table width="100%" height="40" bgcolor="#ededed" border="0" cellpadding="0" cellspacing="0" style="width:100%;height:40px;background:#ededed;border:none;">
  <tr>
    <td width="100%" height="40" bgcolor="#ededed" border="0" cellpadding="0" cellspacing="0" align="center" valign="middle" style="width:592px;height:40px;background:#ededed;border:none;">
      <font height="40" color="#2095f2" size="2" style="line-height:40px;font-size:14px;color:#2095f2;">
        <a href="#" width="100%" height="40" color="#2095f2" style="width:100%; height:40px;line-height:40px;font-size:14px;color:#2095f2;text-decoration:none;display:block">
          詳しく見る
        </a>
      </font>
    </td>
  </tr>
</table>
```

## テーブルでお遊び系

### タグのようなもの

よく見かける線で囲われた中ぬきのタグのようなものをtableタグで書いてみました。

![スクリーンショット 2015-12-21 03.52.05.png](https://qiita-image-store.s3.amazonaws.com/0/19094/dba92ae1-679c-eb26-e592-a67a2c32dfc0.png "スクリーンショット 2015-12-21 03.52.05.png")

こういうの。

ソース量が滅茶苦茶増えるので、ご利用は計画的に…！（Gmailの容量規制でぶった切られて崩れることが有りますので…。）
無駄にoutlook&レスポンシブ対応（笑）

```html
<table width="*" border="0" cellpadding="0" cellspacing="0" align="left" valign="top" style="width: auto; border:none;margin:0 auto;>
  <tr>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="*" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:auto;height:1px;background:#4caf50;border:none;"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
  </tr>
  <tr>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#4caf50;border:none;" class="px1"></td>
    <td width="*" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:auto;height:1px;background:#ffffff;border:none;"></td>
    <td width="1" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#4caf50;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
  </tr>
  <tr>
    <td width="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;line-height:20px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;line-height:20px;background:#4caf50;border:none;" class="px1"></td>
    <td bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="line-height:20px;background:#ffffff;border:none;">
        <table border="0" cellpadding="0" cellspacing="0" style="border:none;margin:0;padding:0;"><tr><td border="0" cellpadding="0" cellspacing="0" style="border:none;margin:0;padding:0;">
          &nbsp;&nbsp;
          <font color="#4caf50" size="1" style="font-size:12px;color:#4caf50;"><b style="font-weight:bold">
            タグのようなもの
          </b></font>
          &nbsp;&nbsp;
        </td></tr></table>
    </td>
    <td width="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;line-height:20px;background:#4caf50;border:none;" class="px1"></td>
    <td width="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;line-height:20px;background:#ffffff;border:none;" class="px1"></td>
  </tr>
  <tr>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#4caf50;border:none;" class="px1"></td>
    <td width="*" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:auto;height:1px;background:#ffffff;border:none;"></td>
    <td width="1" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#4caf50;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
  </tr>
  <tr>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="*" height="1" bgcolor="#4caf50" border="0" cellpadding="0" cellspacing="0" style="width:auto;height:1px;background:#4caf50;border:none;"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
    <td width="1" height="1" bgcolor="#ffffff" border="0" cellpadding="0" cellspacing="0" style="width:1px;height:1px;background:#ffffff;border:none;" class="px1"></td>
  </tr>
</table>
```

```css
body .px1 {
  width: 1px !important;
  table-layout: fixed !important;
}
```

随時、小ネタやコピペで使えるソース集などアップデートしていけたらと思います。