テンプレートを使って作成されたHTMLメールがOutlookで盛大に崩れていたので調整してみた


普段はwebサイトのHTMLを修正するのがメインの自分に、「幅の設定がおかしいから調整してみて」と依頼があり実際各メーラーで確認したところ幅の設定どころではなかった。


- Gmail(PC): 表示される画像が画面をはみ出している
- Outlook(PC): 背景画像が表示されない
- ThunderBird(PC): 設定している横幅を貫通して要素が横並びになっている
- Android EmailApp: 背景画像が表示されない

なんとか無難に表示できるようにはしたので
調べた内容をまとめておく





## 参考ページ
- [@IT記事](http://www.atmarkit.co.jp/ait/articles/1007/14/news103.html)
- [vml参考記事](http://www.s-arcana.co.jp/tech/2012/03/htmloutlook2007.html)
- [各メーラー仕様](https://www.campaignmonitor.com/css/)

## viewportについて
- よくある width="device-width" はスマートフォン表示に必須
- initial-scale=1.0 は幅決め打ちの要素がある場合にandroidで解釈がおかしくなる(device-widthを無視して、決め打ち幅に対してのパーセンテージになる)
    - 例としては、幅600pxでラップしたHTMLメールをinitial-scale=1.0でAndroidで表示するとそのまま600pxで表示されて画面をはみ出す
    - この場合余計な指定はせずに device-widthだけの指定にすると 画面にぴったりおさめてくれる
    - ※もしくはすべてpxではなく%で設定してmax-widthで調整すればいい
    - 幅をpx固定ではなくすべて%で指定することでview-portが適切に設定される
    - ベースの幅はmax-widthで指定する必要がある
    - この場合Outlookで表示がおかしくなるので 条件付コメントで Outlook用のwrapperを設定するといい。

## 主要メーラーの癖
- Outlook(cssがほとんど効かない、Microsoft Office Wordがベースになっているので,Wordで出来ない事は出来ない)
- Gmail（styleタグが効かない）
- Thunderbird(tableがインライン扱いでラッパーを貫通するため display:block; でうまく修正する)
- Android全般(view-portがうまく設定されないことがある)

## レスポンシブレイアウトについて
- viewportを設定する
- メディアクエリーはGmailが使えないのでNG
- OutlookではCSSのfloatプロパティに対応していない
- Gmail は `<body>` を自動的に `<div>` に置き換えるため、body をセレクタに使ってスタイル指定をしても効かないので注意
- Yahoo! Mail のメディアクエリのバグ（今はもう解消済み）への対応のため、メディアクエリ内で属性セレクタを使ってスタイルを指定している場合は要注意
- 横幅は500～600pxで作成する
- 作成したPC向けのHTMLメールをベースに、スマートフォン向けの対応をする
- tableはフロートのような挙動をするのでうまく使う

## 作成手順として
プログレッシブ・エンハンスメント( 最低限古いブラウザでも表示できる状態にしてから、新しいコードを付け足していく )で作成する

0. 基本
    - 基本テーブルのみで組む
    - 上下の余白はtdのheight属性で設定する
    - 横幅はすべて%で指定する
    - ベースの幅はmax-widthで指定する
    - Outlookのベース幅はpx固定したtableを条件付コメントで設定する

1. Android 対策
    - すべて%指定にする ~~はみ出すし、背景画像が効かない。代替策もない~~
    - 妥協策として背景画像を似た背景色で設定
    - ~~はみ出すのはしょうがない（ これに合わせようとするとOutlook,Gmailでも360px幅で作成する必要がある )~~
    - ブラウザで表示できるようにリンクを設定するのは必須
    - Androidのviewportの解釈がおかしいので、指定はwidth="device-width"のみにする ? 要検討
    - フッター下に100px程度の余白を持たせる（Androidの特定のデバイスでフッター部分がUIに隠されてしまう場合がある）
        -（他に解決法あるのだろうか...）

2. Gmail + Outlook 対策
    - Gmail対策
        - まずはテーブルとstyle属性でベースを決める （Gmailではstyleタグが無視されるので、最低でもこの条件で表示に問題ないようにする）
            - ※ 2016年に対応するニュースがあったが2016/12現在も使えない
    - Outlook対策
        - Outlookで表示を確認する (崩れたり、表示されなかったりする場合は以下チェック)
            - 背景画像は効かない -> VMLを使用する (VMLではpositionが使用できるのでabsoluteをつかって重ねることができる)
            - レスポンシブにならない -> あきらめる。Outlookの場合600px固定となるように設定する

3. ThunderBird 対策
    - デフォルトではtableにラッパーが効かないので、効かせたいtableタグにdisplay:blockを指定する

## スニペット

### 基本のテーブル
- tableはデフォルトだと余計な枠やセル内の余白が設定されているのでリセットする
- colspanやrowspanを使わないように組み立てる


```html
<table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="仕様に応じて" align="仕様に応じて">
    <tr>
        <td>
        </td>
    </tr>
</table>
```


- border="0"　ボーダーを消す
- bgcolor="ffffff"　デフォルトの背景色をリセット
- cellpadding="0"　セル内の余白をリセット
- cellspacing="0"　セルの枠を削除
- border-collaps:collaps　ボーダー同士を重ねる（念のため）
- mso-table-lspace:0pt　MicrosoftOffice独自仕様をリセット
- mso-table-rspace:0pt　MicrosoftOffice独自仕様をリセット

### 縦の余白
テーブルをつかって余白を設定する

```html
<table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="仕様に応じて" align="仕様に応じて">
    <tr>
        <td height="任意の高さ">
        </td>
    </tr>
</table>
```

### センタリング
幅100%に設定したテーブル内に任意の幅を設定したテーブルを入れてセンタリングする

```html
<table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="100%" align="center">
    <tr>
        <td>

            <table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="50%" align="center">
                <tr>
                    <td>
                        center
                    </td>
                </tr>
            </table>

        </td>
    </tr>
</table>
```

### Wrapper
ThunderBirdではdisplay:blockを適切なtable要素に指定する必要がある

```html
<table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="ラップの幅" align="仕様に応じて">
    <tr>
        <td>
            ...
        </td>
    </tr>
</table>
```

### 3カラム
各table要素の幅の合計が100%になるように指定する

```html
<table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="100%" align="center">
    <tr>
        <td>

            <!-- col 1 -->
            <table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="33%" align="left">
                <tr>
                    <td>
                        left
                    </td>
                </tr>
            </table>

            <!-- col 2 -->
            <table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="33%" align="left">
                <tr>
                    <td>
                        center
                    </td>
                </tr>
            </table>

            <!-- col 3 -->
            <table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="34%" align="left">
                <tr>
                    <td>
                        right
                    </td>
                </tr>
            </table>

        </td>
    </tr>
</table>
```



### vmlで背景画像を設定
#### html属性を設定

```html
<html xmlns:v="urn:schemas-microsoft-com:vml">
```

#### cssハックを設定

```html
<style>
    v:* { behavior: url(#default#VML); display: inline-block; }
</style>
```

#### vmlを設定
1. v:rect は四角形を作成する
2. v.fill で色をつけたり背景画像を設定したりできる
3. v.shape が実際に表示される部分。大きさを決めうちする

※条件付コメントは必須の様子（外すと表示されない）

```html
<!--[if gte mso 9]>
    <v:rect style="position:relative;left:0;width:600px;height:384px;" strokecolor="none">
        <v:fill type="tile" src="http://path/to/image.jpg"></v:fill>
    </v:rect>
    <v:shape id="theText" style="position:absolute;width:600px;height:384px;top:-5;">
<![endif]-->

        <table border="0" bgcolor="ffffff" cellpadding="0" cellspacing="0" style="border:0; border-collaps:collaps; mso-table-lspace:0pt; mso-table-rspace:0pt;" width="仕様に応じて" align="仕様に応じて">
            <tr>
                <td>
                    ... 背景画像に乗せたいテキスト ...
                </td>
            </tr>
        </table>

<!--[if gte mso 9]>
    </v:shape>
<![endif]-->
```

※追記
Gmailに送られたメールをOutlookに転送すると表示されない
届いたメールには条件付きコメントが設定されているが、転送されたメールのコードでは削除されているため表示されない