CSSの仕様では@charset
は先頭に置かれたものしか効果を発揮しない。最近は共にUTF-8でHTMLとCSSを書くだろうと思うので、あまり使われず、気にすることはもうあまりない。ただ何かしらの事情があって使う場合、カジュアルにファイルを連結してプロダクション用のCSSを作成すると、無意味な場所に@charset
が出てきて無駄が多くなる。
ちゃんと書かれていることを前提にすると、ブラウザーの処理の仕方と同じように先頭以外の@charset
を問答無用に削除しても良い。しかし、Normalize.cssのような最初に読ませる必要があるライブラリと@charset
が必要なCSSファイルを連結するケースではそれではダメになる。最初に見つけた@charset
を先頭へ移動させるというような形が一番マシだろう。
異なる@charset
が指定されたCSSファイルを連結する時におかしなことになるが、そのCSSは壊れてるので気にする必要はない。
CSSWringには結構前から@charset
を最初に見つけたものだけにしてそれを先頭へ持っていく機能がある。今まではグローバル変数として@charset
が既出かどうかのフラグを持たせて処理してたけど、以下のように書き換えた。
if (atRule.name === 'charset') {
atRule.removeSelf();
var first = atRule.parent.first;
if (first.type !== 'atrule' && first.name !== 'charset') {
atRule.parent.prepend(atRule);
}
return;
}
とりあえず削除して、もし親の最初のルール(aRule.parent.first
)が@charset
でなかったら追加するという形にした。こうするとグローバル変数を使ったフラグ管理をしなくて済む。
このあたりのことを色々調べてて知ったんだけど、先日書いた通り@import
では直後の空白類を削除できるけど、@charset
では削除できないことになっていた("@charset " {return CHARSET_SYM;}
となっている)。文字コードを括る引用符を省略できるわけでもないし、なんでなんだろうか。歴史的な事情はありそう。