並列したボックスの中身を揃えたい

スタッフブログ

皆さんこんにちは。webデザイナーのハナフサです。
横並びになっている要素の高さを揃えたいけど、中身の大きさが違うのでうまいこと高さが合わない。このような問題に悩まされました。調べてみると、同じような悩みを持っている人もいたので、CSSのみを使って解決する方法を2通りご紹介します。

左右のボタンの位置を揃える

上の図を見ればだいたい想像できると思いますが、今回は左右のボタンの位置を揃えていきます。そのためにやりたくない解決方法上げると、中身の大きさが変わるたびにその都度何かしらのCSSの変更を加えることです。たとえば、heightなどの数値を固定すると中身の大きさが変わった時にはみ出してしまうことがあるので、中身の大きさによらずボタンは同じ位置で揃うように指定をしていきたいと思います。

初期状態のHTMLとCSS

初期状態でのHTMLとCSSです。これをもとにどのように対応していけばよいか、2パターンを紹介していきます。

<!-- HTML -->
        <div class="wrap">
            <div class="list">
                <h3 class="title">タイトルタイトルタイトルタイトル</h3>
                <p class="text">
                    テキストテキストテキストテキストテキストテキストテキスト
                    テキストテキストテキストテキストテキストテキストテキスト
                    テキストテキストテキストテキストテキストテキストテキスト
                    テキストテキストテキストテキストテキストテキストテキスト
                </p>
                <button>ボタン</button>
            </div>
            <div class="list">
                <h3 class="title">タイトルタイトル</h3>
                <p class="text">
                    テキストテキストテキストテキストテキストテキストテキスト
                </p>
                <button>ボタン</button>
            </div>
        </div>
/* CSS */
/* 装飾のスタイルは省いています。 */
.wrap {
  display: flex;
}

flex-growでtextクラスの高さを揃える

なぜボタンの位置が揃わないのかというと、最初の辺りでも触れてますが中身の大きさが違うためです。この例だとテキストの量によって高さが異なるため、直後のボタンの位置が揃いません。なので逆を言うと、テキストの高さを等しくするとボタンの位置も等しくなります。

それを実現するプロパティーがflex-growです。.list内の残りの空間のうち、どれだけ.title.textbuttonに割り当てるかを設定します。ここでは、テキストの高さを高くしたいので、.titlebuttonには指定せず.textのみにflex-grow: 1;を指定し、.listの残りの空間すべてを割り当てます。

.list {
  display: flex;
  flex-direction: column;
}
.text {
  flex-grow: 1;
}

気をつける点としては、.textの親要素にdisplay: flexを指定する。flexboxの機能にflex-growが備わっているので以下のように指定する必要があります。

positionでbuttonクラスの位置を固定

他に考えられる方法は、buttonの位置を固定させることです。.listに相対配置relativeを指定し、buttonに絶対配置absoluteを指定します。そうすることで、中身のコンテンツを無視してボタンの位置を決めれます。

.list {
  position: relative;
}
.text {
  margin-bottom: 2em; /* ボタン分空ける */
}
.button {
  position: absolute;
  bottom: 1em;
  left: 0;
  right: 0;
  margin: 0 auto;
}

気をつける点としてはposition:absolute;の設定だけだと、ボタンはその他要素を無視して配置されているのでテキストと被ってしまいます。なので、.textに対してmargin-bottom.listpadding-bottomで、ボタン分幅を空けて下の余白を作っておくことで、被らないようにします。

おわり

今回は、並列したボックスの中身を揃える方法を紹介しました。positionflex-growを使用しましたが、プロパティーの指定する値によってどんな動きをするのかなど、それぞれ特徴を理解したうえで使用することが大切だと思います。