CSS ショートハンド・プロパティの問題点

CSS のショートハンド・プロパティは複数のプロパティを一括して宣言できますが、メンテナンスしづらくなったり、思わぬバグの原因になったりすることがあります。そしてその問題が見えにくいことがさらに面倒です。font プロパティ を例に、実際にどのような弊害があるのか検討してみます。

html {
    font: 87.5%/1.5 "Georgia", serif;
}

このショートハンドは一見すると次の 3 つのプロパティをひとまとめにしたものに見えます。

html {
    font-size: 87.5%;
    line-height: 1.5;
    font-family: "Georgia", serif;
}

しかし、font プロパティは上記のほか font-stylefont-variantfont-weight プロパティも指定でき、そして省略されたプロパティには初期値が割り当てられます。つまり、実際には以下のように宣言されていることになります。

html {
    font-style: normal;
    font-variant: normal;
    font-weight: normal;
    font-size: 87.5%;
    line-height: 1.5;
    font-family: "Georgia", serif;
}

さて、このショートハンドで書かれたコードをチームで共有する場合を考えてみます。ひょっとするとこのコードを書いた人は、明示されているプロパティのみを宣言したかったのであり、プロパティの省略とそれに伴う暗黙の初期化については意図していなかったのかもしれません。しかしコードを読む人にとってはそこに記述されているコードがすべてなので、それはすべて意図的なものと捉えるしかありません。つまり、ここでは font-stylefont-variantfont-weight の値として normal を指定する必要がある、と読むことになるわけです。こうしてコードに対する認識の食い違いが生まれ、本来は必要のないスタイルが定義され、そして最悪の場合にはバグを生むことになります。

ただ実際のところ、htmlbody 要素に対して font プロパティを宣言するのはいわゆるリセットやノーマライズ的な意味での場合が多いので、上記の例が問題になることはあまりないかもしれません。しかしそれはレンダリング結果にたまたま影響がないだけで、やはり表面化していない問題が潜んでいるのだと思います。

もうひとつの例として、HTML5 Boilerplate の画像置換テクニック のコードを見てみます。

.ir {
    font: 0/0 a;
    text-shadow: none;
    color: transparent;
}

この font プロパティのうち、ここでのスタイルの要件を満たすために必要なのは font-sizeline-height のみです。font-family は必要ないのですが、構文上省略できないため、せめてコードを短くしたいという理由で書体名ではなく a という文字列が宣言されています。また省略された 3 つのプロパティに初期値を指定する必要もありません。しかしこのようにトリッキーな記述をされると、あとから編集する人が手を入れることが難しく、内容が検討されないまま「おまじない」としてコピペされ続けてどこかで思わぬ弊害を生んだり、逆に検討しようとすると無駄な時間がかかったりする可能性があります。こういったハック寄りのテクニックではとくに、必要最低限の記述にとどめるべきでしょう。

font プロパティのほかにも、たとえばブロックボックスを親要素の左右中央に配置するスニペット margin: 0 auto; は上下まで指定する必要があるか検討すべきだし、background プロパティなんかはいい加減に書いてると思わぬ結果を招くことがよくあるので、やはりショートハンド全般に注意が必要です。

というわけで、ショートハンド・プロパティはコードが短くすっきりする反面、余分なプロパティを宣言してしまうことがあり、かつそれが意図されたものかどうかわかりづらくなってしまう、という問題があります。やはりその都度必要なプロパティだけを宣言するよう心掛けるのが良いのではないでしょうか。CSS の場合、そういった余分な宣言があっても結果的に問題が表面化しないということも多いので、なかなか意識するのが難しいところではありますが、このあたりを考慮できると、将来にわたって安全で運用しやすい CSS に一歩近づけるように思います。