Web アプリケーションのレイアウトに flexbox を使用する

flexbox は、デスクトップからモバイルまで対応する Web アプリケーションのレイアウト設計で助けになります。浮動状態の <div> 要素、絶対位置指定、JavaScript による細工をなくして、数行の CSS だけで水平方向または垂直方向のフローレイアウトを構築します。基本的な用途例を挙げます:

  • ページの中央に要素を置きたい場合。
  • コンテナを垂直方向へ次々に並べて配置したい場合。
  • スクリーンサイズが小さいときに垂直方向へ並べ替えられる、ボタンや要素の列を作成したい場合。

この記事では、接頭辞がない現行の標準仕様をサポートするブラウザで flexbox を使用する方法を扱います。古いブラウザ向けのベンダー接頭辞については、CSS flexible box の使用に関する、より一般的なガイドをご覧ください。

基本

任意の <div> 要素で display プロパティに flex を、また flex-flowrow (要素を水平に並べたい場合) または column (要素を垂直に並べたい場合) を設定すると、内部の要素を flexbox のフローにすることができます。水平方向の flexbox を使用していて内容物を垂直方向に折り返したい場合は、値 wrap も指定します。

そして、flex フローの一部として組み込みたい要素に flex プロパティを指定します。通常、以下の 3 種類の値のいずれかを使用するでしょう:

  • ボタンなど、自身に割り当てられた幅を占有するだけの要素にしたい場合は、flex: none を使用します。この値は 0 0 auto に展開されます。
  • 要素のサイズを明示したい場合は、flex: 0 0 size を使用します。例: flex 0 0 60px
  • 使用可能な領域を埋めるように拡張する要素にしたい、すなわちフロー内に同種の要素が複数ある場合は均等に領域を共有させたい場合は、flex: auto を使用します。この値は 1 1 auto に展開されます。

もちろん他にも使用できる値はありますが、それらは基本的な使用方法を超えるものでしょう。これらの値がどのように適用されるかを、いくつかの例で見ていきましょう。

ページ内の中央に要素を配置する

このような使い方でもっとも簡単な方法は、2 つの flexible box を入れ子にすることです。それぞれの flexbox 内に要素が 3 つあります。そのうち 2 つが詰め物になって、残る要素が中央に置かれます。

CSS コンテンツ

.vertical-box {
  display: flex;
  height: 400px;
  width: 400px;
  flex-flow: column;
}
.horizontal-box {
  display: flex;
  flex-flow: row;
}
.spacer {
  flex: auto;
  background-color: black;
}
.centered-element {
  flex: none;
  background-color: white;
}

HTML コンテンツ

<div class="vertical-box">
  <div class="spacer"></div>
  <div class="centered-element horizontal-box">
    <div class="spacer"></div>
    <div class="centered-element">Centered content</div>
     <div class="spacer"></div>
  </div>
  <div class="spacer"></div>
</div>

結果

複数のコンテナを垂直方向に並べる

ヘッダーセクション、コンテンツセクション、フッターセクションがあるレイアウトのページを思い浮かべてください。ヘッダーとフッターのサイズは固定しますが、コンテンツセクションは使用できる領域に応じてリサイズします。これはコンテンツセクションの flex プロパティを auto に、またヘッダーおよびフッターの flex プロパティを none にすることで実現できます。

CSS コンテンツ

.vertical-box {
  display: flex;
  height: 400px;
  width: 400px;
  flex-flow: column;
}
.fixed-size {
  flex: none;
  height: 30px;
  background-color: black;
  text-align: center;
}
.flexible-size {
  flex: auto;
  background-color: white;
}

HTML コンテンツ

<div id="document" class="vertical-box">
  <div class="fixed-size"><button id="increase-size">Increase container size</button></div>
  <div id="flexible-content" class="flexible-size"></div>
  <div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
</div>

Javascript コンテンツ

var height = 400;
document.getElementById('increase-size').onclick=function() {
  height += 10;
  if (height > 500) height = 500; 
  document.getElementById('document').style.height = (height + "px");
}

document.getElementById('decrease-size').onclick=function() {
  height -= 10;
  if (height < 300) height = 300; 
  document.getElementById('document').style.height = (height + "px");
}

結果

この例はヘッダーのボタンをクリックするとサイズが拡大、フッターのボタンをクリックするとサイズが縮小するようになっています。ヘッダーやフッターのサイズを一定にしたままで、どのようにしてコンテンツセクションを自動的に適切なサイズに変えているかを確認してください。

折り返される水平方向のコンテナを作成する

スクリーンサイズに余裕があれば水平方向に情報一式を並べますが、そうでない場合は水平方向のレイアウトを崩したい場合があるかもしれません。これは、flexbox を使用すればとても簡単です。flex-flow プロパティに値 wrap を追加すると実現できます。

CSS コンテンツ

.horizontal-container {
  display: flex;
  width: 300px;
  flex-flow: row wrap;
}
.fixed-size {
  flex: none;
  width: 100px;
  background-color: black;
  color: white;
  text-align: center;
}

HTML コンテンツ

<div id="container" class="horizontal-container">
  <div class="fixed-size">Element 1</div>
  <div class="fixed-size">Element 2</div>
  <div class="fixed-size">Element 3</div>
</div><button id="increase-size">Increase container size</button><button id="decrease-size">Decrease container size</button>

Javascript コンテンツ

var width = 300;

document.getElementById('increase-size').onclick=function() {
  width += 100;
  if (width > 300) width = 300; 
  document.getElementById('container').style.width = (width + "px");
}

document.getElementById('decrease-size').onclick=function() {
  width -= 100;
  if (width < 100) width = 100; 
  document.getElementById('container').style.width = (width + "px");
}

結果

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: yyss
 最終更新者: yyss,