メディアクエリの順番が崩れることがあるバグを修正して、CSS MQPackerのv0.1.2をリリースした。CSSは順序に依存するものなので、やっぱり書いたままの順を維持した方が良いのかな……などと、このツールの根本を否定するような考えが頭をよぎった。

これまでは、同じ条件のメディアクエリが出てきた時に、それまでにあったメディアクエリのブロックを新しく出てきたメディアクエリのブロックへマージするという実装だった。必要な物を必要なだけ動かすことになるので、良い実装と勘違いしていたんだけど、以下の様なCSSを通すと破綻する。

.foo { color: black; }

@media (min-width: 300px) {
  .foo { color: red; }
}

@media (min-width: 600px) {
  .foo { color: green; }
}

.bar { color: black; }

@media (min-width: 300px) {
  .bar { color: blue; }
}

メディアクエリの条件が(min-width: 600px)のものはひとつしかないので、このメディアクエリのブロックは移動されない。そのため処理結果のCSSは以下のようになり、600px以上の時も.fooは赤色の文字になる。

.foo { color: black; }

@media (min-width: 600px) {
  .foo { color: green; }
}

.bar { color: black; }

@media (min-width: 300px) {
  .foo { color: red; }
  .bar { color: blue; }
}

新バージョンでは、逐次メディアクエリのブロックを削除しながら別にマージしていき、最後にCSSへ追加するようにした。メディアクエリは最後にまとめられることになる。上記例を新バージョンで処理すると以下のようになり、ちゃんと600px以上の時に.fooが緑色の文字になる。

.foo { color: black; }

.bar { color: black; }

@media (min-width: 300px) {
  .foo { color: red; }
  .bar { color: blue; }
}

@media (min-width: 600px) {
  .foo { color: green; }
}

これで大丈夫なんじゃないかと思う。