コンテンツ枠内のボタンを一番下に固定配置するCSS6パターン

2021年7月19日

コンテンツ内に横並びのメニューを作った時、例えば「詳しくはコチラ」のようなボタンがテキスト量によってズレて表示されてしまっていたので、それを回避する方法を色々考えてみました。

メニュー枠を作るhtmlはいくつかありますが、ボタンの固定については、大きく「abusoluteで固定する方法」と「flexboxを使う方法」の2種類を紹介します。
どちらも見た目には大差無いと思います。

仕上がりイメージ

テスト画像

テキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

詳しくはこちら

やりたい事

  • ボタンは枠の下部に固定
  • ボタンサイズにwidthを指定した上で、ボタンを左右中央に配置させる
  • テキスト量が変わっても、それぞれの枠の縦幅は同じ高さに揃うようにする
  • 枠はheight固定しない

※メニュー枠はflexで横並びにしています。

align-items: stretch;を指定することで、テキスト量が変わっても枠の高さが揃うようになります。

【参考】flexのCSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}

リンクボタンを下部固定する6パターン

  • absoluteで配置する(divを使用)
  • absoluteで配置する(ul liを使用)
  • absoluteで配置する(dl dt ddを使用)
  • flexboxで配置する(divを使用)
  • flexboxで配置する(ul liを使用)
  • flexboxで配置する(dl dt ddを使用)

absoluteで配置する(divを使用)

リンクボタンをpositon:absoluteで、枠の下部に固定させる方法です。

単純に下部に固定させるだけだと、下の右側の枠のようにテキストとボタンが重なってしまいます。

テスト画像

テキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

詳しくはこちら

HTML

<div class="inner_box">
	<div class="test">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキスト</p>
		<a href="#" class="button">詳しくはこちら</a>
	</div>
	<div class="test">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキストテキストテキストテキストテキスト</p>
		<a href="#" class="button">詳しくはこちら</a>
	</div>
	<div class="test">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
		<a href="#" class="button">詳しくはこちら</a>
	</div>
</div>

CSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	box-sizing:border-box;
}
a.button {
	position: absolute;
	bottom: 10px;
	display: block;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	left: 50%;
	line-height: 30px;
	transform: translateX( -50%);
}

対策

ボタンの高さと同じだけ、CSSにpadding-bottomを追加します。

今回の場合、ボタンのline-heightが30pxなので、CSSの.testにpadding-bottom:30pxを追記するか、padding: 10px 10px 30px 10px;と修正します。

padding-bottom:30pxと記述する場合は、必ずpadding: 10px;より下の行に追記して下さい。

なお、今回のパターンでは、リンクボタンを左右中央に配置するためにleft: 50%;と設定した上でtransform: translateX( -50% );と設定しています(ボタンが改行されてしまう場合はwhite-space:nowarp;を追記してみて下さい)。

CSS(.test部分のみ)

.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	padding-bottom: 30px;
	box-sizing:border-box;
}
テスト画像

テキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

詳しくはこちら

これで、ボタンとテキストが重ならなくなりますが、更新(メンテナンス)時に以下の注意点があります。

問題点

ボタンサイズを変更する場合、.testのpadding-bottomもサイズを変更する必要がある(更新時に面倒)。

absoluteで配置する(ul liを使用)

基本的には上記と同じです。

HTMLにdivを使わずulliを使うので、divが入れ子にならずにソースが分かりやすい(かもしれない)と思っています。

一方で、liで画像、テキスト、リンクボタンを区切るので、ul(この場合.test)にlist-style:noneが必要になります。

また、ボタンの入るli(この場合li:last-of-type)にpadding-bottom:30pxを記入します。

仕上がりイメージ

  • テスト画像
  • テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
  • 詳しくはこちら

HTML

<div class="inner_box">
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキスト</li>
		<li><a href="#" class="button">詳しくはこちら</a></li>
	</ul>
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキストテキストテキストテキストテキスト</li>
		<li><a href="#" class="button">詳しくはこちら</a></li>
	</ul>
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</li>
		<li><a href="#" class="button">詳しくはこちら</a></li>
	</ul>
</div>

CSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	padding-bottom: 30px;
	box-sizing:border-box;
	list-style:none;
}
a.button {
	position: absolute;
	bottom: 10px;
	display: block;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	left: 50%;
	line-height: 30px;
	transform: translateX( -50%	);
}

余談ですが、line-heightの関係でテキストとボタンが詰まっている等の問題があれば、CSSを以下のようにしても良いかと思います(実際の私のソースでは以下のように設定しています)。

CSS(.test関連部分のみ)

.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	box-sizing:border-box;
	list-style:none;
}
.test li:last-of-type {
	padding-bottom: 30px;
}

absoluteで配置する(dl dt dd を使用)

基本的な構造は上記と同じです。

ulliを使用したパターンより、CSSが若干シンプルになる印象です。

dtddは1:1でなくて良いので、dt1つに対してddを2つ設定しています。

仕上がりイメージ

テスト画像
テキストテキスト
詳しくはこちら
テスト画像
テキストテキストテキストテキストテキストテキスト
詳しくはこちら
テスト画像
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
詳しくはこちら

HTML

<div class="inner_box">
	<dl class="test">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキスト</dd>
		<dd><a href="#" class="button01">詳しくはこちら</a></dd>
	</dl>
	<dl class="test03">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキストテキストテキストテキストテキスト</dd>
		<dd><a href="#" class="button01">詳しくはこちら</a></dd>
	</dl>
	<dl class="test03">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</dd>
		<dd><a href="#" class="button01">詳しくはこちら</a></dd>
	</dl>
</div>

CSS

	.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	padding-bottom: 30px;
	box-sizing:border-box;
}
a.button {
	position: absolute;
	bottom: 10px;
	display: block;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	left: 50%;
	line-height: 30px;
	transform: translateX( -50%);
}

flexboxで配置する(divを使用)

2つ目の大きな方法はflexboxでリンクボタンを下部固定する方法です。

posision:abusoluteの場合と異なり、padding-bottomで調整する必要がなくなります。

具体的には、inner_box内の子要素.testにもflexを設定します(詳細は下記ソースをご覧ください)。

CSS(.testのみ)

.test{
	display:flex;
	align-items: flex-start;
	justify-content: flex-start;
	flex-direction: column;
}

flexboxを使いつつ、flex-direction: column;を設定する事でコンテンツ内の画像、テキスト、リンクボタンを縦並びにします。

こちらの方法もdivul lidl dt ddを使用した方法を紹介します。

こちらの方がメンテナンス性は良さそうですが、下記3パターンそれぞれでCSSの記述が若干異なるので若干汎用性に欠けるかなぁ、というのが個人的見解です。

HTML

<div class="inner_box">
	<div class="test">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキスト</p>
		<a href="#" class="button02">詳しくはこちら</a>
	</div>
	<div class="test04_box">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキストテキストテキストテキストテキスト</p>
		<a href="#" class="button02">詳しくはこちら</a>
	</div>
	<div class="test04_box">
		<img src="画像パス" alt="テスト画像">
		<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
		<a href="#" class="button02">詳しくはこちら</a>
	</div>
</div>

CSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	box-sizing:border-box;
	display:flex;
	align-items: flex-start;
	justify-content: flex-start;
	flex-direction: column;
}
a.button {
	display: block;
	margin: auto auto 0 auto;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	line-height: 30px;
}

今回のパターンでボタンを下部固定するにはdisplay:blockを設定した上で、margin-topをautoに設定します。

また、左右中央に配置するにはmargin-leftmargin-rightをautoに設定する必要があります。

そのため、a.buttonの箇所はmargin: auto auto 0 auto;としています。

できあがったのもの

テスト画像

テキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキスト

詳しくはこちら
テスト画像

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

詳しくはこちら

flexboxで配置する(ul liを使用)

HTML

<div class="inner_box">
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキスト</li>
		<li class="button"><a href="#">詳しくはこちら</a></li>
	</ul>
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキストテキストテキストテキストテキスト</li>
		<li class="button"><a href="#">詳しくはこちら</a></li>
	</ul>
	<ul class="test">
		<li><img src="画像パス" alt="テスト画像"></li>
		<li>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</li>
		<li class="button"><a href="#" >詳しくはこちら</a></li>
	</ul>
</div>

CSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	box-sizing:border-box;
	list-style:none;	
	display:flex;
	align-items: flex-start;
	justify-content: flex-start;
	flex-direction: column;
}
.button {
	display: block;
	margin: auto auto 0 auto;
}
.button a {
	display: block;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	line-height: 30px;
}

ulliを使用するので、abusoluteのパターン同様、.testにlist-style:none; を設定します。

また、今回のパターンの場合、リンクボタンを下部固定および左右中央に配置させるためには、aではなく、ボタンの入るli<li class="button">と設定する必要があります。

できあがったもの

  • テスト画像
  • テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
  • 詳しくはこちら

flexboxで配置する(dl dt dd を使用)

HTML

<div class="inner_box">
	<dl class="test">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキスト</dd>
		<dd class="button"><a href="#">詳しくはこちら</a></dd>
	</dl>
	<dl class="test">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキストテキストテキストテキストテキスト</dd>
		<dd class="button"><a href="#">詳しくはこちら</a></dd>
	</dl>
	<dl class="test">
		<dt><img src="画像パス" alt="テスト画像"></dt>
		<dd>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</dd>
		<dd class="button"><a href="#">詳しくはこちら</a></dd>
	</dl>
</div>

CSS

.inner_box {
	display:flex;
	align-items: stretch;
	justify-content: space-between;
}
.test {
	position: relative;
	width: 30%;
	background: #f5f5f5;
	border: 1px solid #ddd;
	padding: 10px;
	box-sizing:border-box;
	display:flex;
	align-items: flex-start;
	justify-content: flex-start;
	flex-direction: column;
}
.button {
	display: block;
	margin: auto auto 0 auto;
}
.button a {
	display: block;
	width: 100px;
	background: #338DC9;
	color: #fff;
	text-decoration: none;
	font-size: 12px;
	text-align: center;
	line-height: 30px;
}

基本的には上記ulliを使用したパターンと同じです。

dtddは1:1でなくて良いらしいので、ddを2つ作ってリンクボタンが入るものに<dd class="button">と設定しています。

ulliのパターンと同様に<dd class="button">にリンクボタンが下部固定および左右中央配置させる設定をしています。

できあがったもの

テスト画像
テキストテキスト
詳しくはこちら
テスト画像
テキストテキストテキストテキストテキストテキスト
詳しくはこちら
テスト画像
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
詳しくはこちら