Gmailが<font>を使ってるって、フォントうですか？

## HTMLメールの大罪

HTMLメールは、その前時代的なマークアップで悪名高い。HTMLの発展に生涯を捧げてきたティム・バーナーズ=リー博士は苦々しく思っているのではないか。

主にWordなどの独自連携を重視してきたOutlookのせいで（今年中に新バージョンが出るとの噂があるが、旧式デスクトップ版が駆逐されるまで何年かかることだろう）、いまだにHTML5相当の要素やCSS3が使えない（せめて`<style>`を埋め込めればいいのに）という体たらく。eMail業界でも[Interop](https://wpt.fyi/interop-2022)向上活動が起こってほしいものである。需要はあまりにも高いにもかかわらず、業界が動かないというのは本当に疑問だ。

さて、そんなHTMLメールの例としてGmailを紹介する。

## GmailのHTML

GmailでテストHTMLメールを作ってみた。

![サンプルメールの見た目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666342/6b6e2fd7-c807-2a18-c06f-dff106f2ad65.png)

こんな見た目は大したことないメールだが、実際に生成されるHTMLはすごいことになっている。

```html
<div class="">
  <div class="aHl"></div>
  <div id=":1e8" tabindex="-1"></div>
  <div id=":1dx" class="ii gt" jslog="20277; u014N:xr6bB; 4:W251bGwsbnVsbCxbXV0.">
    <div id=":1dw" class="a3s aiL ">
      <div dir="ltr">
        <div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">サンセリフ</div>
        <div class="gmail_default" style="color:rgb(0,0,0)">
          <font face="times new roman, serif">セリフ</font>
        </div>
        <div class="gmail_default" style="color:rgb(0,0,0)">
          <span style="font-family:arial,helvetica,sans-serif">
            <font size="6">最大サイズ</font>
          </span>
        </div>
        <div class="gmail_default" style="color:rgb(0,0,0)">
          <span style="font-family:arial,helvetica,sans-serif">
            <font size="1">最小サイズ</font>
          </span>
        </div>
        <div class="gmail_default">
          <span style="font-family:arial,helvetica,sans-serif">
            <b style="color:rgb(0,0,0)">太字</b>
            <i style="color:rgb(0,0,0)">斜め</i>
            <u style="color:rgb(0,0,0)">下線</u>
            <span style="background-color:rgb(255,255,0)">
              <font color="#6fa8dc">色変更</font>
            </span>
          </span>
        </div>
        <div class="gmail_default">
          <span style="font-family:arial,helvetica,sans-serif">
            <span style="background-color:rgb(255,255,0)">
              <font color="#6fa8dc"><b><i><u>まとめて指定</u></i></b></font>
            </span>
          </span>
        </div>
        <div class="gmail_default" style="text-align:center">
          <span style="font-family:arial,helvetica,sans-serif">
            <font color="#000000">中央</font>
          </span>
        </div>
        <div class="gmail_default" style="text-align:right">
          <span style="font-family:arial,helvetica,sans-serif">
            <font color="#000000">右</font>
          </span>
        </div>
        <div class="gmail_default" style="text-align:left">
          <ol>
            <li>
              <span style="font-family:arial,helvetica,sans-serif">
                <font color="#000000">リスト</font>
              </span>
            </li>
            <li>
              <span style="font-family:arial,helvetica,sans-serif">
                <font color="#000000">リスト</font>
              </span>
            </li>
          </ol>
          <ul>
            <li>リスト</li>
            <li>リスト</li>
          </ul>
        </div>
        <blockquote style="margin:0 0 0 40px;border:none;padding:0px">
          <div class="gmail_default" style="text-align:left">インデント</div>
        </blockquote>
        <div class="gmail_default" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">
          <strike>取り消し線</strike>
        </div>
        <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"
          class="gmail_quote">
          <span class="gmail_default"
            style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">引用</span>
          </blockquote>
        <div>&nbsp;</div>
        (宛先)
      </div>
      <div class="yj6qo"></div>
      <div class="adL">
      </div>
    </div>
  </div>
  <div id=":1ec" class="ii gt" style="display:none">
    <div id=":1ed" class="a3s aiL "></div>
  </div>
  <div class="hi"></div>
</div>
```

カオスである。文字以外が入る可能性が高いので`<p>`ではなく`<div>`を使っているのは百歩譲って分かるが、用途不明の`<div>`が混入したりしていて見通しが悪い。サンセリフは`<div>`で書式設定されているにもかかわらず、セリフはそうではない。というよりあれ…見たことない要素が混じっているぞ。

## `<font>`？ 死んだはずじゃ？

残念だったな、現役だよ。

セリフのフォント指定やサイズ指定に、なぜか`<font>`要素が使われている。これはHTML4の段階ですでに非推奨になり、現行仕様では完全に廃止された機能である。奇怪なことに、Gmail開始はすでにHTML4が普及しきった2004年である。`style`の`font-family`指定と`<font>`の`face`属性が入り乱れる様は単純に不快である。HTMLパーサーはどうなってるんだ？　スパゲッティコードのように思えるのは私だけではあるまい。サイズや色の変更のたびに`<font>`が使われているのは解せない。

また、取り消し線はこれまたお亡くなりになったはずの`<strike>`が使われている。むしろデッドボールと言いたくなる。

おまけに、インデントを入れるとその要素は`<blockquote>`である。セマンティックとは一体…スクリーンリーダーユーザーの困惑する顔が目に浮かぶ。

こんなメタメタなパーサーだから、自分は使いたくない。**通常メールならプレーンテキストモードで十分である**。見た目に頼りすぎではなかろうか。

## HTMLを掃除してみた

このコードを動く程度に整理してみるとどうなるだろう。Googleが内部で使っているのだろうが、表示に関係ない謎の`<div>`もついでに削除させてもらう。

``` after.html
<div dir="ltr" style="font-family:arial,helvetica,sans-serif;color:rgb(0,0,0)">
  <p class="gmail_default">サンセリフ</p>
  <p class="gmail_default" style="font-family:'times new roman',serif;">セリフ</p>
  <p class="gmail_default" style="font-size:24px">最大サイズ</p>
  <p class="gmail_default" style="font-size:10px;">最小サイズ</p>
  <p class="gmail_default">
    <strong>太字</strong>
    <em>斜め</em>
    <span style="text-decoration: underline;">下線</span>
    <span style="background-color:rgb(255,255,0);color:#6fa8dc;">色変更</span>
  </p>
  <p class="gmail_default">
    <span style="background-color:rgb(255,255,0);color:#6fa8dc;text-decoration: underline;">
      <strong>
        <em>まとめて指定</em>
      </strong>
    </span>
  </p>
  <p class="gmail_default" style="text-align:center">中央</p>
  <p class="gmail_default" style="text-align:right">右</p>
  <div class="gmail_default">
    <ol>
      <li>リスト</li>
      <li>リスト</li>
    </ol>
    <ul>
      <li>リスト</li>
      <li>リスト</li>
    </ul>
  </div>
  <p style="margin:0 0 0 40px;border:none;padding:0px">インデント</p>
  <p class="gmail_default" style="text-decoration:line-through;">取り消し線</p>
  <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"
    class="gmail_quote">引用</blockquote>
  (宛先)
</div>
```

強めに最適化をかけているので、変更するたびにDOM変更が走ることになるため、メール作成は重たくなるだろう。でも送信データ量（パケット）はかなりセーブされる。89行→36行、3450文字→1322文字と大幅に短くなっている。