以前に書いた のっちメソッド: One pixel notched corners の改良版。まずはスクリーン・ショットを。

「のっちメソッド」のスクリーン・ショット。ボックスの角が 1 px 欠けている表現

Gmail の「ラベル」なんかでも使われている、ボックスの四隅が 1 px 欠けた疑似角丸的な表現。これを CSS のみで実現するテクニックが「のっちメソッド」なわけだが、幅が固定のボックスにしか適用できなかった。そこで上図のように内容に応じて縮む「なりゆき幅」を実現するのが今日のお題。

まずはマークアップ。それぞれのボックスはブロックかインラインかを問わず二重の要素でラップされている必要がある。例えばこんな感じ:

<ul>
  <li><a href="#">HTML/XHTML</a></li>
  <li><a href="#">CSS</a></li>
  <li><a href="#">JavaScript</a></li>
<ul>

CSS では、まず float プロパティで親要素 (この例では li) を横並びにし、上下のボーダーと左右のマージンとを設定する:

li {
  float: left;
  boder: solid #008080;
  boder-width: 1px 0;
  margin: 0 2px;
}

次に内側の要素 (この場合は a) もフロートさせ、パディングと左右のボーダーを指定。そして四隅を欠けさせるためのキモ、左右に -1px のマージンを指定して親要素からはみ出させる。なおここで position: relative も指定しないと IE 6 で意図どおりにはみ出してくれないので注意。

li a {
  float: left;
  padding: 0 0.5em;
  boder: solid #008080;
  boder-width: 0 1px;
  margin: 0 -1px;
  position: relative; /* for IE 6 */
}

以上。完成版のデモ をどうぞ。タブやページ送りなどのナビゲーションなんかに使えるんじゃないだろうか。

幅を明示せずにフロートさせることで、幅がなりゆきで算出される shrink-to-fit アルゴリズム が適用されるわけだけど、今回の例ではフロートのもうひとつの特性も利用している。それは「フロートした要素はその要素タイプにかかわらずブロック・ボックスを生成する」という挙動。これ、あまり知られていないというか、そう言われてみればそうか、という挙動じゃないかな。以下は Eric Meyer の “CSS: Pocket Reference” からの引用:

A floated element will generate a block-level box no matter what kind of element it may be. Floated nonreplaced elements should be given an explicit width, as they otherwise tend to become as narrow as possible.

(Eric A. Meyer, CSS: Pocket Reference)

フロートってテクニックは CSS を習得する過程で最初につまづくとこだと思うんだけど、実は習得したのちにちゃんと振り返る機会があまりないものなのかもしれない。なにしろ習得過程で思いどおりにいかない場面にいやってほど直面してさんざん試行錯誤しているので、いったん習得した (と思えた) らもう考えたくない、ってのはありそうな話。でも以外と挙動を理解してないんだなー、と最近は感じる。まだまだ応用の余地がありそうな気がするんだよね、フロートって。