Flexboxでヘッダーを実装する方法

本稿ではCSSのflexboxを使って、Webサイトのヘッダーを構成する方法を4通りご紹介します。多くのヘッダーは左右にアイテムを配置した構成をしており、本稿でもヘッダーの各メニューを中央に寄せるのではなく、左右に並べる方法をご紹介します。

margin-left: auto

親要素にdisplay:flexを適用すると、デフォルト設定では子要素は行方向(flex-direction: row)の左揃え(justify-content: flex-start)に並びます。ここで最も右側の子要素だけにmargin-left: autoを適用すると、その子要素だけが右側に寄り、他の要素は左側に整列したままとなります。





具体的なコードは次の通りです。クラス名parent-containerが親要素、3つの子要素のクラス名は左側から順番にchild-left、child-center、child-rightとしています。



header.css

.parent-container {
display: flex;
}

.child-left {
margin-left: 16px;
}

.child-center {
margin-left: 16px;
}

.child-right {
margin-left: auto;
margin-right: 16px;
}

最も右の要素ではなく、右からN番目の要素にmargin-left: autoを適用すると、1番目からN-1番目の要素が左側に、N番目以降の要素が全て右側にならびます。

上記のコード例よりもう少し複雑ですが、このブログをPCで見た場合のヘッダーはこの方法を使っています。

justify-content: space-between

現在(2021年5月現在)最も使われている方法です。justify-contentでは、主軸方向の子要素の並び方を定めます。デフォルトでは主軸は行方向です。space-bewteenを指定すると一番初めの子要素を左端に、一番最後の子要素を右端に寄せます。残った要素は名前の通り、要素間のスペースが均等になるように配置されます。



ここで、子要素を2つだけにすると2つの要素を左右に寄せることができます。



実際には下記のように、flexboxの2つの子要素のうちの一方を、さらに子要素を持つflexboxとすることが多いです(親要素から見ると孫要素)。





上記イメージを実装する具体的なコードは次の通りです。クラス名parent-containerが親要素、2つの子要素のうち左側をchild-left、3つの孫要素を持つ右側の子要素をchild-right-containerとしています。



header.css

.parent-container {
display: flex;
justify-content: space-between;
}

.child-left {
margin-left: 16px;
}

.child-right-container {
display: flex;
justify-content: space-between;
column-gap: 8px;
margin-right: 16px;
}

子要素のcolumn-gapでは、孫要素の間隔を8pxに指定しています。また、左右に16pxのマージンを設けています。

実際のサイトでは例えば、dribbbleのヘッダーはこの方法で作られています。ヘッダー全体を親要素としてdisplay: flexとjustify-content: space-betweenを適用した上、左側のdirbbbleのロゴから右に5つ並ぶメニューを括って左側の子要素とし、右側のサーチアイコンからサインアップまでの3つを括って右側の子要素としています。それぞれのメニューやアイコンは親要素から見ると孫要素になります。

Spotifyのヘッダー部分もjustify-content: space-betweenを使っています。

flex: 1

子要素にflex: 1を適用すると、その要素が親要素の余白をめいいっぱいとって伸びるので、その要素が右側にあれば残った要素は左側に、その要素が左側にあれば残った要素は右側に寄せられます。

この方法は、なんらかの事情で子要素間のスペースをなくしたいときに使います。ただし、flex: 1を適用された子要素は横に引き延ばされて縦横比が狂うので、flex: 1が適用される子要素の中にさらに子要素を配置するいれ子構造とする必要があります。flex: 1を適用しない他方の要素は縦横比を維持したまま反対方向に寄せられます。



ヘッダーに応用すると、次のような構成になります。display: flexを適用した親要素の中に2つこの子要素を設置し、右側だけにflex: 1を適用します。右側の子要素にはさらに2つの子要素(親から見ると孫要素)があるとします。





上記イメージを実装する具体的なコードは次の通りです。クラス名parent-containerが親要素、2つの子要素のうち左側がchild-left、2つの孫要素を持つ右側の子要素をchild-right-containerとしています。子要素のcolumn-gapと左右にマージンの指定はjustify-content: space-betweenの事例と同様です。

右側の子要素が左にめいいっぱい伸びているので、justify-content: flex-endによって孫要素を右側に寄せる必要があります。



header.css

.parent-container {
display: flex;
}

.child-left {
margin-left: 16px;
}

.child-right-container {
flex: 1;
display: flex;
justify-content: flex-end;
column-gap: 8px;
margin-right: 16px;
}

ヘッダーではないですが、flex: 1が適用される子要素が伸びる性質を利用し、ヘッダー以外では例えば次のような使い方があります。左側にサーチアイコンを、右側にテキストの入力エリア(inputタグ)を配置します。

ここで右側のinputタグにflex: 1を適用すると、親要素の余白をめいいっぱいに埋めて横に伸びます。左側のサーチアイコンは伸びずにそのままです。

なお、上記の例に使用したサーチアイコンはMaterial UIの<SearchIcon/>を使用しています。Material UIの使い方はこちらの記事で詳しく解説しています。

flex: 0.5とflex-start,-endの組み合わせ

flex: 1と同様に、この方法も子要素間にスペースを置きたくない場合に使います。また、flex:1と同様に親要素の半分のスペースに子要素が引き延ばされるので、ヘッダーで使う場合は孫要素を持ついれ子構造とします。flex:1との違いは、子要素が左右対称に等分される点です。

まずdisplay: flexを適用した親要素の中に2つこの子要素を設置、それぞれにflex: 0.5を適用し、中央で二つに分けます。

続いて、それぞれの子要素にdisplay: flexを適用し、左側にはjustify-content: flex-startを、右側にはjustify-content: flex-endを適用します。そうすると左側の子要素の中の要素(親から見ると孫要素)は左側に寄り、右側の子要素の中の要素は右に寄ります。





親要素のクラス名をparent-container、左側子要素のクラス名をchild-left-cintainer、右側子要素のクラス名をchild-right-containerとすると、上記イメージを実現する具体的なCSSのコードは次のようになります。子要素のcolumn-gapと左右にマージンの指定は前述の事例と同様です。



header.css

.parent-container {
display: flex;
}

.child-left-container {
flex: 0.5;
display: flex;
justify-content: flex-start;
column-gap: 8px;
margin-left: 16px;
}

.child-right-container {
flex: 0.5;
display: flex;
justify-content: flex-end;
column-gap: 8px;
margin-right: 16px;
}

今日も最後まで読んで頂きありがとうございました。