04 September 2009

cssの@charsetルールとchrome, safari

外部cssファイルの先頭以外で@charsetが指定されていると、そのcssファイルの最初の指定がchromeとsafariでは無視されてしまいます。

確認したバージョンは、

  • Chrome: 2.0.172.43
  • Safari: 4.0.3 (531.9.1)

です。

現象

ことの経緯を説明すると、バイト先のサイトがchromeだと表示がおかしいことを発見。調べてみると、body要素へのスタイルシートが効いていないようでした。cssファイルはこんな感じです。

/* comments */
@charset "euc-jp";

body {
/* some styles */
}

原因

body指定の前に空のルールを入れると、直りました。セレクタすら無しの、中括弧のみです。

/* comments */
@charset "euc-jp";

{}        /* empty rule */

body {
/* some styles */
}

また、@charsetを取り除いても上手くいきました。

/* comments */
/* @charset "euc-jp"; */

body {
/* some styles */
}

どうやら原因は@charsetのようです。

@charset (at-rule) の指定の仕方

調べてみると、外部cssファイルの@charsetルールは、ファイルの先頭に書かなければいけないことがわかりました。コメントやスペースが前にあっても駄目です。

Syntax and basic data types

Authors using an @charset rule must place the rule at the very beginning of the style sheet, preceded by no characters.

W3C I18N FAQ: CSS character encoding declarations

Only one @charset rule may appear in an external style sheet and it must appear at the very start of the document. It must not be preceded by any characters, not even comments.

解決法

というわけで、@charsetをファイルの"本当に"先頭に移動することで、解決しました。

@charset "euc-jp";
/* comments */

body {
/* some styles */
}

Safariも同様

もう少し調べてみると、safariでも同様の現象が起こるこが分かりました。解決方法も同じです。

Safari and Chrome issue

まとめ

@charsetルールをファイルの先頭以外に書くと、chromeとsafariでは最初のスタイルが無視されてしまいます。@charsetの前にコメントや空白があっても駄目です。Firefox, IE, Operaではこの現象は確認されていません。cssの仕様には沿っているので、バグというほどではないのですが、気をつけたいところです。