【CSS】Flexboxの中でボタンが大きくなる理由
display:flex
が指定された要素の中に、ボタンを入れると縦方向に大きくなってしまいます。
解決策は、align-self
でcenter
やflex-end
などを指定することです。
CSSはググれば簡単に解決方法が見つかることもあり、今までまともに勉強をしてこなかったので、ここで改めて何故そうなるのか?を調べてみます。
Flexboxとは
アイテムのグループを 1 つの次元でレイアウトするために設計されたレイアウトのための機構です。レイアウトのための機構としてもう一つ代表的なものにGridがありますが、こちらは 2 つの次元でレイアウトすることに適しています。
flex
ある要素のdisplay
属性の値にflex
を指定するとFlexboxでのレイアウトができるようになり(Flex Containerと呼ばれる)、子要素が全て Flex Item になります。
また、冒頭でも述べましたがFlexboxは 1次元 でのレイアウトを行うための機構です。display:flex
を指定した最初の状態では、横軸が主軸に指定されるため内側の要素は横一列に並ぶことになります。この主軸はflex-direction
を使うことによって縦か横かを指定できます。
<div class="container">
<h1> Hello FlexBox</h1>
<h4> subtitle</h4>
<input placeholder="inputfield"></input>
<button>Button</button>
</div>
.container {
display: flex;
justify-content: space-between;
border: solid black;
}
Flexboxについては内容が盛り沢山で時間がいくらあっても足りないので、タイトルにある通りボタンが大きくなる理由を調べます。
もっと詳しく知りたい場合は、collisさんの翻訳記事、もしくはMDNがおすすめです。
flex-item
Flexboxの子要素は全てFlex Itemになります。ということは、ボタンもFlex Itemになっているはずです。それでは、Flex Itemとは何なのでしょうか?
Flex Itemは次のようなプロパティを持ちます。
プロパティ | 説明 | 初期値 |
---|---|---|
align-self | グリッドやフレックスのアイテムの align-items の値を上書する | auto |
flex-basis | フレックスアイテムの初期の大きさ | auto |
flex-grow | フレックスアイテムが大きくなる係数 | 0 |
flex-shrink | フレックスアイテムが小さくなる係数 | 1 |
order | フレックスアイテムを並べる順番 | 0 |
flex-basis やflex-grow も少し難しいのですが、align-self に注目します。align-items の値を上書きするとありますが、align-items とは何でしょうか? |
align-items
グリッドレイアウトやフレックスボックスでのアイテムの位置を制御するためのプロパティ。
フレックスボックスでは、交差軸方向のアイテムの配置を制御します。交差軸とはFlexboxの説明で述べた主軸と垂直に交差する軸のことです。初期状態では主軸が横方向なので交差軸は縦方向です。
aligin-items
の初期値はnormal
です。
align-items:normal
normal
の効果はレイアウトモード(FlexboxやGridのこと)に依存します。
フレックスボックスではstrech
として動作するため、フレックスアイテムも全てstrech
となります。
↑これがボタンが大きくなる理由の答えですね。
strech
の説明には、幅や高さの制約の大きさが拡張されますとあるので、ボタンが可能な限り大きくなってしまったようです。
よって、ボタンなどの伸ばしたくない要素にalign-self:flex-end
などと指定すると縦に伸びなくなり、全ての要素に適用したい場合はalign-items
にcenter
などを指定すると全てが中心に揃います。
button {
align-self: flex-end;
}
.container {
display: flex;
justify-content: space-between;
align-items: center;
border: solid black;
}
感想
解決策を見つけるだけなら一瞬で終わりますが、何故を追求すると無限に時間が溶けて行きそうです。調べている中でも分からないこと(フレックスコンテナーのベースライン、マージンボックスのcross-size)や面白そうな機能(display
の2値構文)などがありCSS沼は底なしです。
本記事を書くきっかけとなった、個人的なアドベントカレンダーも読んでいただけると嬉しいです。(ジャンルはごった煮です。)
Discussion