Unformed Building

要素内容に依存する幅の指定について

公開:
更新:

パーマリンク

要素内容に依存する幅の指定についてのメモです。
これらは「CSS basic box model(草案)」に記載されており、MDNのページに分かりやすく説明されています

本来、これらは幅だけでなく高さの指定にも使えるようなのですが、まだ実装されていませんので確認できません。
2013年4月現在、幅の指定として使えるブラウザはFirefoxとGoogle Chromeです。Safariでは動くんですかね。最新版ないから分かりません。

available or fill-available
包含ブロックから該当要素のマージン、ボーダー、パディングのサイズを引いた幅。
現在、Firefoxは-moz-available、Chromeは-webkit-fill-availableで動作します。
max-content
ややこしい計算式があるんですが、とりあえずは該当要素が取りうる最大の幅として覚えておけばいいかと。
min-content
同様に、該当要素が取りうる最小の幅として覚えておけばいいかと。
fit-content
max(‘min-content’, min(‘max-content’, ‘available’))ということなので、max-contentavailableを比較して小さい幅、そしてそれとmin-contentを比較して大きい幅となります。

実際に試してみます。まだ-moz--webkit-が必要なので、使う場合は忘れずに。
スクリーンショットはFirefox 20でのものです。

min-content, max-content, fit-content 1

<div class="box">
  <p class="min">Lorem ipsum dolor sit amet</p>
</div>

<div class="box">
  <p class="max">Lorem ipsum dolor sit amet</p>
</div>

<div class="box">
  <p class="fit">Lorem ipsum dolor sit amet</p>
</div>
.box {
  margin: 0.5em auto 1em;
  padding: 0.5em 1em;
  width: 400px;
  background: #aaa;
}

.box p {
  margin: 0;
  padding: 0.5em 1em;
  background: #faa;
}

.min {
  width: min-content;
}

.max {
  width: max-content;
}

.fit {
  width: fit-content;
}

これではmax-contentfit-contentの違いが分からないのでもうちょっと文章を長くしてみましょう。

min-content, max-content, fit-content 2

min-content, max-content, fit-content サンプル 2

違いが分かるでしょうか?

で、これは何が便利なの、ってところですが。
人によって使い道は様々でしょうが、そこそこ実用的かなと思うものを考えてみました。

まずはmin-contentから。
画像とキャプションの幅を揃え、水平中央配置します。画像の幅が決まっているなら最初からpx単位で指定とかすればいいんですが、どんなサイズの画像が入るか分からない場合などに使えます。
最大値が必要ならmax-widthに数値で入れておくといいです。

画像サイズ依存のキャプション幅

min-contentを使った画像サイズ依存のキャプション幅の例
<figure>
  <img src="..." alt="" />
  <figcaption>
    Lorem ipsum dolor sit amet...
  </figcaption>
</figure>
figure {
  margin: 1em auto;
  width: -webkit-min-content;
  width: -moz-min-content;
  width: min-content;
}

max-contentでは、floatを使った横並びメニューのセンタリングが簡単にできます。
「Flexbox使えば?」って話ではあるんですが、それはそれということで。

横並びメニューのセンタリング

max-contentを使った横並びメニューのセンタリング例
<ul>
  <li>Lorem</li>
  <li>ipsum</li>
  <li>dolor</li>
  <!-- ... -->
</ul>
ul {
  margin: 1em auto;
  padding: 0.5em;
  background-color: #aaa;
  width: -webkit-max-content;
  width: -moz-max-content;
  width: max-content;
}

ul::after {
  display: block;
  clear: both;
  content: "";
}

li {
  float: left;
  padding: 0.5em 1em;
  background-color: #aaf;
  list-style-type: none;
}

li:nth-child(even) {
  background-color: #afa;
}

fit-contentは……max-contentを使いたいけど親要素より大きなサイズにはしたくないときなんかに便利なんじゃないでしょうか。
いい例が思いつかなかったのでサンプルはありません。

それと、Webkit系ブラウザにはintrinsicというfit-contentっぽい動きをするキーワードがあります。これはChromeでも確認できます。試してみたところ、Android 4.1のブラウザでも動きました。2.2でも動作を確認しました。
min-intrinsicというのもあるようなのですが、実際に使えるのかどうか分かりません。試してみても効いてる気がしないんですよね……。
MDNにはWebkitのintrinsicmax-contentの古いものだと書かれていましたが、「Bug 38919 – Add support for fit-content etc」を見た感じだとfit-contentと同じように扱ってるっぽいですね。