ホームページ制作 オフィスオバタ

display: flexで、高さを統一しているときに、特定要素のみ高さをフリーにする

ホームページ制作をしていると、2列構成や3列構成にすることもしばしばあります。
以前ならfloat指定でカラムを構成していました。
ですが、最近ではdisplay:flexなるスタイルシートが増え、おもったより簡単に列構成レイアウトができるようになりました。

display:flexは、floatと異なり、「高さ」が存在します。
それゆえ、複雑な構造もレイアウトできます。

例えば3列2行構成の場合、align-items: flex-start;指定をすれば、同一行で同じ高さに揃えられます。
ですが、レイアウト上次のようなことをする必要がありました。

特定のboxだけ、高さをフリーにする。

全部高さをそろえる、全部フリーにするは簡単にできます。
align-items: flex-start;を指定する、しないで済むからです。

ですが、他のboxは高さをそろえ、特定の1個だけ高さをフリーにすることなんてできるの?
半信半疑でしたが、やってみたらできました。

忘備録として記録いたします。

やりたいことは次の通りです。

全部で6つのboxがあり、それぞれ行ごとに高さが揃うようにしています。
実際は1行分しかいないboxも2行分の高さになっています。
ですが、4個目のboxのみ高さを他のboxに引きずられることなく、高さを自由にしたいのです。

論より証拠。実際にできたものがこちらです。

できてしまえばあっけないものですが、その理屈がわかるまで少し手間取りました。
なぜならばflex指定には、多くのオプション指定があるからです。

それがflexの使い方を分かりにくくしている部分でもあります。

まず最初にやってみたのがこちら

まずは以下のようなコーディングをしてみました。

<!doctype html>
<html>
<head>
<meta charset="shift_jis">
<title>無題ドキュメント</title>
<style type="text/css">
.box 
{
	width: 1000px;
	margin-right: auto;
	margin-left: auto;
}

ul
{
	display: flex;
	justify-content: space-between;
	gap: 30px;
	padding-right: 60px;
	align-items: stretch; 
	flex-wrap: wrap;
}

ul li
{
	display: block;
	border: 1px solid #000;
	width: 30%;
	text-align: center;
}
</style>
</head>
<body>
<div class="box">
<ul>
<li>1<br>改行</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5<br>改行</li>
<li>6</li>
</ul>
</div>

</body>
</html>

ulにflex指定をして、align-items: stretch;指定で高さをそろえています。

当然ですが、高さが揃います。
4番だけ高さをフリーにしたいのですが、これではだめです。

高さそろえをしないとこうなりました。

ならばと、align-items: flex-start;指定をなしにしたところ、4番以外のboxの高さもフリーになりました。

基本は、box同士で高さを揃えたいため、align-items: flex-start;指定は必須です。
ではどうすればよいのでしょうか?

個別指定で高さ揃えをキャンセルする

要は、4番目のliタグだけ、高さ揃えをキャンセルできればOKなのです。
そんな都合の良い指定ができるのか?
と思いましたが、ちゃんと用意されていました。
それがこちらの記述です。

ul li:nth-of-type(4)
{
	align-self: flex-start;
}

意味合い的には、liタグの4番目だけ、高さ揃えを初期値(上揃え)にするという意味です。

上揃えなのでstretchと違い、高さがフリーになります。

ここで疑問がわきました。
:nth-of-type(4)指定と同じようなものに、:nth-child(4)があります。
今回の例だと、どちらを指定しても、同じ結果になります。

では、違いは何だろう?

ついでに調べてみました。

:nth-of-typeと:nth-childの違い。

どちらも子要素の何個目を指定するものです。
ulタグ内のliタグを指定する場合等では、結果が同じになります。

ではなぜ、同じ動きをするものが2種類あるのか?
調べてみました。

:nth-childは子要素すべてを数えます

例えば以下の記述の場合、3コメのliタグを指定します。

ul li:nth-child(4)
{
	align-self: flex-start;
}

<ul>
<li>1個目</li>
<li>2個目</li>
<div>divタグ</div>
<li>3個目 ←これを示します</li>
<li>4個目</li>
</ul>

そもそもulタグ内にdivタグを入れるのもおかしいとは思いますが、もし入っていた場合、1つの子要素としてカウントされます。

ちなみに、:nth-child(3)を指定したらどうなるのか試してみたところ、どれも選択されないという状態になりました。3番目はdivタグだけれども、liタグを指定しているので、選択されない。

:nth-of-typeは指定要素だけを数える

それに対し、:nth-of-typeは、指定要素だけを数えます。
以下の記述だと、4個目のliタグが選択されます。

ul li:nth-of-type(4)
{
	align-self: flex-start;
}

<ul>
<li>1個目</li>
<li>2個目</li>
<div>divタグ</div>
<li>3個目</li>
<li>4個目 ←これを示します</li>
</ul>

:nth-of-typeは、指定したタグだけを数えます。
なので、:nth-childの場合は、3個目のliタグが指定されましたが、:nth-of-typeの場合は、divタグを飛ばして、4個目のliタグが指定されます。

レイアウトする要素タグがバラバラな場合は、:nth-child、レイアウト要素タグが統一されている場合は:nth-of-typeが良いのかもしれません。

思いもよらない解決方法の見出し方

今までは、ググって調べ、試してダメならまたググるを繰り返していました。
ですが今回は、AIを使って調べました。
AIは、想像もしなかった解法を示してくれるので、新たな発見をすることが多いです。

ただ、AIに指示された通りにやっても上手くいかないことも多いので、ググるとAI併用が良いのかもしれません。

モバイルバージョンを終了