レガシーブラウザーに立ち向かうCSSハック

# 序

## 20年前の状況

もはや自分のおじさんレベルをばらすこと以上ではないですが、20年前のウェブ開発状況は革新的でした。それにつれ、色んな新概念、新単語が現れ始めました。

### ウェブ標準

今は耳にしないくらい一般化した「ウェブ標準」という概念が咲き始めた頃です。
これは、圧倒的な占有率を持っていたIE（Internet Explorer）が、専用の開発規格を強要したことにあります。HTML、CSS、さらにはJavascriptでもIEで動かせるためには独自の規格に従わないといけなかったです。IE6以後シェア率が落ち始めたMSはこの事態を打開しようとIE7などいろいろ出しましたが、今は大体Edgeに切り替わってます。

### パブリッシャー

若手の開発者は先輩から聞いたことがあるかもしれませんが、その頃には「パブリッシャー」という開発ポジションがありました。役割としては、今のフロントエンドエンジニアに相当するウェブデザイナーの中で、「デザインよりHTMLやCSSを書きたい」という集団になります。
HTMLとCSSは、今は別格に区切るほどの技術や作業量ではないです。
しかし、テーブルレイアウトが主流だったそのごろは、Webページというものは大体テーブルタグとインラインCSSで作られていたので、その専門の担当者がいるのは大変助かりました。

### スクリプター

その頃バックエンド（サーバー側）は大体JavaやPHP、ASP.NETの一つでした。しかし、フロントエンド（クライアント。前述したパブリッシャー）で使う動的コード（主にJavascript）をバックエンドの人が担うことが当たり前になっていました。
最悪の場合、パブリッシャーが作ったテーブルレイアウトがバックエンドの想定に合わない場合も多かったので、雛形になるHTMLまでバックエンドが組むことも珍しくなかったです。この方々の名残が「フルスタック」という単語です。
当然のことくバックエンドの作業を助けるため、Javascriptに特化した人が担ったそのポジションを「スクリプター」と呼び始めました。
このスクリプターがやっていた以外の仕事の一つが、Flashの開発です。Flashで使っているAction ScriptはJavascriptと同じくECMA Script規格でしたので、文法や単語もそのまま使えました。

### Ajax

この頃登場した新技術、Ajax（Javascriptの非同期通信）のおかげで、この辺のパブリッシャーとスクリプターは将来フロントエンドというポジションに成長します。

### CSSハック

こういう技術の発展とは遠く、CSSの改善はそこまで追いついてなかったです。
そのため、ウェブ標準のCSSと前述したIEのCSSの表示が異なる場合が多かったです。
しかも、IE6以後のIE7,8,9（もう全てのIEと言いましょう）は各々の表示をしていたので、それを補完するための技術が必要となってきました。
それが「CSSハック」です。

# 本

では、ここではCSSハックの具体的な例を見てみましょう。

## IE6以下

```
*html .selector {
  // ここにIE6以下で表現したいCSSを記述
}
```

## IE7

```
*:first-child+html .selector {
  // ここにIE7で表現したいCSSを記述
}
```

```
*+html .selector {
  // ここにIE7で表現したいCSSを記述
}
```

## IE7以上

```
html>body .selector {
  // ここにIE7以上で表現したいCSSを記述
}
```

## IE7以上モダーンブラウザー

```
html>/**/body .selector {
  // ここにIE7以上で表現したいCSSを記述
}
```

## IE8

```
.selector {
  /* 以下はIE8専用 */
  /*\*/property: value\9;/*/
}
```

## IE9

```
.selector {
  property: value\9; /* IE9以下 */
  property: value\0; /* IE9のみ */
}
```

## IE10

```
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
  .selector {
    property: value; /* IE10のみ */
  }
}
```

## IE10

```
@supports (-ms-ime-align: auto) {
  .selector {
    property: value; /* IE11のみ */
  }
}
```

## firefox

```
@-moz-document url-prefix() {
  .selector {
    property: value; /* Firefoxのみ */
  }
}
```

## Opera9以下ブラウザー

```
html:first-child{
  // ここにOpera9以下で表現したいCSSを記述
}
```

## Opera

```
@media all and (min-resolution: 0.001dpcm) {
  @media {
    .selector {
      property: value; /* Operaのみ */
    }
  }
}
```

## モダーンな書き方

条件コメント`<!--[if IE]>`やブラウザー別のPolyfillなどを使ったら簡単に回避できます。

## Floatレイアウトの鈍服薬

最近は`flex`や`grid`の適用で気にしない問題ですが、`float`を設定した`div`要素の高さを合わせるのはあまりにも難しかったです。高さが合わないとのことは、単純に高さの問題だけでなく背景色やボーダーの表現にも影響します。
そのため、`clearfix`という強力な解決策が使われていました。`float`要素が設定された親要素は子要素の高さを無視しますが、これを使ったら親要素が子要素の高さを認識します。

```
div::after { // 親要素の最後に仮想要素を追加します。
  content: ""; // 仮想要素の内容を空に設定します。
  display: block; // 仮想要素をblock要素に設定してDOMに追加します。
  clear: both; // 仮想要素がFloat属性を解除します。
}
```

## それ以外の注意点

1. IEで文字の前に閉じタグがあったら大文字になってしまいます。

2. Firefoxでは`tr`、`td`にborderを設定できますが、IEでは`td`だけに設定できます。

3. IEでは`float`と`clear`を同時に指定すると上段余白ができてしまいます。この場合、`width`を`auto`以外に設定したら正常に見れます。

4. IEでは`block`要素が`center`になれません。`block`要素でも`text-align: center;`で指定します。下位要素には`text-align`を`left`または`justify`に指定します。

5. IEで`float`を設定した`div`の後ろにコメントをつけると位置がずれます。コメントを消すか、要素の中に入れます。

6. IEでコラムの幅が合わなくて右側のコラムが下にずれてしまいます。この場合は左のコラム（`width`と`padding`が設定している）要素に`overflow: hidden;`を指定します。

# 結

昔のノートを見つけたら、当時遭遇した色んな問題と解決策が書いてありました。今は不要ですけど、こんなに苦労してた時期があったなって、感じたので痕跡を残しておきます。