Hail2u.net

pre要素へのスタイル指定

idea * ideaでエントリになっていたので、言及されていることだしうちのサイトのことだけちょっと書こうかなとか考えてみたら結構色々あって、エントリのネタになりそうだったのでまとめてみた。どっかにもちょろっと書いたけど。

実際にスタイル指定を書く前に抑えておくべき知識として以下のようなものが挙げられると思う。

  1. ほとんどのブラウザでpreは等幅フォントで表示される
  2. ほとんどのブラウザでprewhite-spacepreになっている
  3. フォント・ファミリを指定する場合は最後にGeneric font familiesが必要になる
  4. overflow: scroll;では縦横どちらにあふれた場合でも縦スクロール・バーと横スクロール・バーが両方とも出る
  5. overflow: auto;ではあふれた方向にのみスクロール・バーが出る
  6. Internet Explorerではoverflow: auto;は内容があふれる場合にうまく解釈されないことがある
  7. heightを指定しなければ内容に合わせて適当に拡大してくれるので縦にはあふれない
  8. Internet Explorerでは内容に合わせてボックス幅が際限なく拡大するのでoverflowと同時にwidthの指定が必要になる
  9. Internet Explorerではボックス・モデルの解釈に問題があるのでwidthと同時にpaddingborderを指定する場合はwidth: 90%;などと余裕を持たせる必要がある

他にもありそうだけど、とりあえず以上を踏まえてスタイル指定を書くと、

pre {
  padding: 1em;
  border: 1px solid #000;
  width: auto;
  _width: 90%;
  overflow: auto;
  _overflow: scroll;
  color: #000;
  background-color: #f6f6f6;
  font-family: 'MS Gothic', monospace;
}

というようなコードになる。サンプル・ページも用意してみた。FirefoxOperaSafariでは横にあふれる場合にのみ横スクロールバーが表示される。Internet Explorerでは常に縦スクロール・バーと横スクロール・バーが現れてしまうので美しくないが、floatによるレイアウトを妨げたりはしなくなる(後述)。overflow-xを利用すれば横スクロールバーだけになるが、Internet Explorerではpreの最下段の一部が隠れてしまったりすることがありオススメできない。ということで、結局は上記のようなコードになるんじゃないかと思う。

overflowを指定する意味は、コードを読みやすくするためではなく(むしろ読みづらくなるはず)、内容に合わせてボックス幅が際限なく拡大するというInternet Explorerの問題点に対する解決のために使っているというのが一般的だと思う。overflowを指定しないと、preの内容が横に長い場合にその親のボックス幅がpreの幅に合わせて拡大してしまうので、floatによるレイアウトを行っている場合などでは、レイアウトが崩れる原因になる。あとはなるべく横スクロールバーが出ないようにするためとかいう意味もあると思う。

idea * ideaの当該エントリでは文字実体参照にどうやって変換するのかとかについても書かれているが、それは利用しているツールに依存する話だと思う。はてなダイアリーにはコードを書く時のためのスーパーpre記法というのがあるし、他のblogツールなどでもプラグインなどであるんじゃないかとか。このサイトの場合は、パブリッシュする時にHTMLに変換するPerlスクリプトに文字実体参照に変換する機能を付けているので、書く時は何も考えずにコピペしてくるだけで良いようにしていたり。

ちなみに、このサイトでは、

div#contents div.story pre {
  margin: 1.5em auto;
  padding: 1em;
  border: 1px solid #cfccc6;
  clear: both;
  width: 90%;
  overflow: scroll;
  color: #333333;
  background-color: #edeae4;
}

div#contents div.story > pre {
  overflow: auto;
}

というコードになっている(フォント指定は別)。アンダースコア・ハックはあまり好きではないので、子セレクタ・ハックを使ってる。