width: fit-contentを使った、ちょっとした配置テクニック
公開:
ウェブページの本文エリア内で、たとえば補足や余談などのデザインを区別して配置したいという場合があります。
その際、そのブロックのレイアウトを次の条件にしたいとします。
- ブロック全体をインデントする
- ブロック内テキストの行頭は揃える
- ブロック内のもっとも長い行の末は本文の行末に揃える
これが実際に使われた場合、表示されるパターンはおおよそ3つ、そしてその複合パターンがあります。
短い1行パターン 長い1行パターン 複数行パターン 複数行、複数段落のパターン
これらのレイアウトを1つの部品として作成したいと思います。
(この記事のコードには現在は必要だとしてもベンダー接頭辞は記載していません)
<section>
<h2>見出し</h2>
<p>本文</p>
<aside class="digression">
<p>余談のようなもの</p>
</aside>
<p>本文</p>
</section>このようなHTMLで、レイアウトを作成します。
なお、クラス名digressionの子要素は1つとは限らず、その内容の長さも不定とします。
このレイアウトを実現するためにfit-contentキーワードは非常に優秀で、単純なコードで実現することができます。
.digression {
margin-left: auto;
padding-left: 3em;
width: fit-content;
}padding-leftで、最低限確保したい左の空白を指定します。margin-leftは、要素を右側に移動させる指定です。margin: 0 autoを使った中央寄せや、FlexboxでFlex itemを左や右に寄せるのにも使われているのを頻繁に見かけるので、みなさんご存知でしょう。
そしてwidthにfit-contentキーワードを指定します。
たった3行で終了です。
そうです。近いことは しかし、この方法ではマージンの相殺が発生する場所としない場所について考える必要があります。 こちらのメリットは そうです。近いことは おや、こちらもたったの3行ですね。 しかし、この方法ではマージンの相殺が発生しないことについて考える必要があります。 こちらのメリットは「今後は安定していそう」というところでしょうか。fit-contentについては2013年にも書いていますが、あのころとは状況が違っていて、fit-contentは関数になる予定です。
そうなったときには、このコードは動いていない可能性が高いです。
しかし関数としてのfit-contentは、現在ではCSS Gridで見慣れていることでしょうし、そちらのほうが馴染みやすいかもしれません。それFloatでできるよ!
floatを使えば実現できます。.digression {
float: right;
margin-left: 3em;
}
.digression + * {
clear: both;
}
今回のデモの場合はp要素のマージンを下方向に統一することで回避できます(デモページは調整していません)。fit-contentが使えないブラウザーでも対応可能なことです。それGridでできるよ!
display: gridを使えば実現できます。.digression {
display: grid;
justify-content: end;
margin-left: 3em;
}
今回のデモの場合はクラス名digression要素の前後の要素、または自身の子要素の最初と最後のマージンを調整する必要があります(デモページでは調整していません)。
fit-contentを使ったコードは将来的な不安はあるものの、マージンの相殺について考えなくてもよいというのは非常に楽です。
このレイアウトの場合、対応している環境に向けて@supportsを使って分離し、そうでない環境にはインデントだけしておく、またはtext-align: rightしておくだけでも十分な気がします。
もしくはFloatを使っておくか。
どの方法も一長一短なので、やるなら好きなものを選べばよいと思います。