CSS MQPackerに加わったソート機能は完全なものではない。完全なものを実現するのが難しいこともあるが、必要とされていないからでもある。メインはmin-width
クエリーに絞り、それ以上は自前で用意してもらうというのは妥協であると同時に、僕の能力の限界でもある。
メディア・クエリーにおいてmin-width
クエリーは以下のいずれかの書かれ方をする。
(min-width: 100px)
(min-width: 100em)
(min-width: 100px) and (min-width: 200px)
not (min-width: 100px)
print and (min-width: 100px)
print, (min-width: 100px)
CSS MQPackerのソート機能はこれらすべてを対象にするわけではない。
シンプルなもの
もちろんmin-width
クエリーのみのものは対象になる。この種類のクエリーにはscreen
など主要なメディア・タイプを含むこともある。後述するが特別に無視されるのはprint
と同時に指定された場合だけだ。
単一のmin-width
クエリーがpx
単位を使って書かれている場合には話は単純で、それらの値を取り出して昇順にソートする。世の7割近くのメディア・クエリーはこれでカバーできるのではないかと思われる。
単位の違い
px
単位以外で書かれることももちろんあるし、混ざることもある……かもしれない(このウェブサイトでは混ざっている)。単位の違いは完全に吸収することは出来ない。CSS 2.1の時代からそうだが、CSSのみでは異なる単位間の完全な変換は行えないからだ。v*
単位はもちろん、pt
やpc
も無理がある。それら対応していない単位を使っている場合には、例えmin-width
クエリーであってもソートの対象には含まれない。
ch
em
ex
px
rem
ソート対象に含まれる単位は以上の5つになる。これらの単位をpx
単位に変化した上で昇順にソートするというわけだ。em
とrem
は16px
を基準に、ch
とex
に関しては初期フォントをArialのNormalと仮定して変換している。
複数のmin-width
本当は意味が無いのだが、クエリーにはand
キーワードを使って複数のmin-width
クエリーが含まれることもあるかもしれない。min-width
クエリーの場合、複数指定されるとその最も大きい値で発動することになる(and
は論理積だからだ)。
そのため、複数のmin-width
クエリーが見つかった場合は、その中で最大の値を取り出し、それのみを使ってソートを行うことになる。
否定のクエリー
メディア・クエリーではnot
キーワードを使ってそのクエリーを否定することができる。min-width
クエリーの場合はmax-width
クエリーとほぼ同じような扱いになると考えて良いだろう。
これらはソートに含める必要はないので、無視する。
printメディア・タイプ
印刷向けスタイルシートはそれなりに需要が増えてきた。今はPDFで印刷するなども手軽に行えるようになったので、そこそこ提供しているウェブサイトも増えてきた印象だ。もちろんmin-width
クエリーと組み合わさって、用紙の大きさによって調整を行うこともあるだろう。
多くの場合はスクリーン向けと印刷向けのCSSを混ぜて書くことはないと思われるため、これも無視する。本当はprint
メディア・タイプを含むクエリーを特別扱いしてやると良いのだろうが、まだそこまでの需要はないだろう。
クエリー・リスト
メディア・クエリーでは複数のクエリーをリストにして指定することもできる。その場合、カンマ区切りで指定してやることになる。このカンマは論理和になるORと同じ意味を持つので、カンマで区切られたクエリーのいずれかにこれまでのルールに従い対象とするクエリーがあった場合、ソートされる。
例え他にprint
メディア・タイプを含むクエリーがあったとしても、だ。
CSS MQPackerではこのようにしてソートの対象を選び出し、それらのみをソートする。対象ではない他のクエリーは、元のCSSファイルでの出現順を維持してまとめられる。また、ソートされたクエリーは他のクエリーの前に配置されるので、印刷向けCSSが意図せず前に来てしまうなどということは起こらない。
概ねうまく動作していることと思われる。バグはもちろん、対象を広げて欲しいなどといった要望は是非イシューを立てて欲しい。
そのうち英語でリポジトリーのWikiにちゃんと書きたい。