CSS MQPackerの行うソート

CSS MQPackerに加わったソート機能は完全なものではない。完全なものを実現するのが難しいこともあるが、必要とされていないからでもある。メインはmin-widthクエリーに絞り、それ以上は自前で用意してもらうというのは妥協であると同時に、僕の能力の限界でもある。

メディア・クエリーにおいてmin-widthクエリーは以下のいずれかの書かれ方をする。

  1. (min-width: 100px)
  2. (min-width: 100em)
  3. (min-width: 100px) and (min-width: 200px)
  4. not (min-width: 100px)
  5. print and (min-width: 100px)
  6. print, (min-width: 100px)

CSS MQPackerのソート機能はこれらすべてを対象にするわけではない。

シンプルなもの

もちろんmin-widthクエリーのみのものは対象になる。この種類のクエリーにはscreenなど主要なメディア・タイプを含むこともある。後述するが特別に無視されるのはprintと同時に指定された場合だけだ。

単一のmin-widthクエリーがpx単位を使って書かれている場合には話は単純で、それらの値を取り出して昇順にソートする。世の7割近くのメディア・クエリーはこれでカバーできるのではないかと思われる。

単位の違い

px単位以外で書かれることももちろんあるし、混ざることもある……かもしれない(このウェブサイトでは混ざっている)。単位の違いは完全に吸収することは出来ない。CSS 2.1の時代からそうだが、CSSのみでは異なる単位間の完全な変換は行えないからだ。v*単位はもちろん、ptpcも無理がある。それら対応していない単位を使っている場合には、例えmin-widthクエリーであってもソートの対象には含まれない。

  1. ch
  2. em
  3. ex
  4. px
  5. rem

ソート対象に含まれる単位は以上の5つになる。これらの単位をpx単位に変化した上で昇順にソートするというわけだ。emrem16pxを基準に、chexに関しては初期フォントを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にちゃんと書きたい。