CSSのflexboxを使ってボックスをタイル状に並べる

flexboxでよくあるタイル状にボックスが並んだレイアウトを作る方法と考え方まとめ💡

ベーシックなタイル状のレイアウト

flexboxで作るタイル状のレイアウト

同じボックスをきれいに整列させていく一番ベーシックなレイアウト。ショッピングサイトのアイテム一覧や、ブログ記事のアーカイブページなどでもおなじみ。
HTMLはなんだってよいのですが、今回はリスト形式です。

<ul>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
  <li>box</li>
</ul>

ブラウザや親要素の横幅に依存させる場合は、widthなどの値は全て%にします。今回は、どんなブラウザサイズで見たときにも、ボックスを横に4つ並べたいので、

(ボックスのwidth + 左右のpadding + 左右のmargin + 左右のborderの)× 4 = 100%

になるように、ボックスのサイズを計算します。

box-sizing:border-box;でボックスの幅にボックスのpaddingとborderの太さを含むように計算方法を変更している場合はこちら👇

(ボックスのwidth + 左右のmargin )× 4 = 100%

今回は、ボックスのwidthを21%、上下左右のmarginを各2%としてレイアウトします。

計算式 : ( 21% + 2% + 2% ) × 4 = 100%

ul{
   display:flex;
   flex-wrap:wrap;
   list-style:none;
   margin:0;
   padding:0;
 }
 li{
   width:21%;
   margin:2%;
   height:180px;
   line-height:180px;
   background:#c3c3c3;
   text-align:center;
 }

これで、上下左右均等にボックスを配置できました。
ちなみに、flexboxの子要素(フレックスアイテム)のmarginは相殺されないので注意!
また、marginを%で指定する場合は、上下左右とも親要素のwidthに対する%になるので上下左右均等な間隔になる。

このレイアウトの場合、flexboxの親要素が1000pxだった場合、
ボックスのwidthは 1000px × 21% = 210px で、
上下左右のmarginは 1000px × 2% = 20px になるので、
ボックスとボックスの間隔は 20px + 20px = 40px になる💡

フレックスアイテムのマージン

Demo

画面いっぱいに写真とテキストを交互に配置するレイアウト

画面いっぱいに写真とテキストを交互に配置するレイアウト

左右のボックスセットにして繰り返すタイプのレイアウト。画像とテキストをセットにして繰り返すパターンが多いですね。ボックスの幅が一定ではないのがステキに見えるポイント。

今回のHTMLはテキストと画像のセットを繰り返すイメージなのでarticleを繰り返すことにします。

<article>
  <div class="text">
    <h1>texttext</h1>
    <p>texttext</p>
  </div>
  <div class="logo">
    <img src="logo.png" alt="logo">
  </div>
</article>
<article>
  <div class="text">
    <h1>texttext</h1>
    <p>texttext</p>
  </div>
  <div class="logo">
    <img src="logo.png" alt="logo">
  </div>
</article>

HTML的に先にテキストがあってそれに対する画像がある方が美しいと思うので、上記のようなHTMLに。.logoと.textを交互に入れ替える部分は、CSSで作ります。

例えばレスポンシブで、1カラムで表示するときのことを考えてもHTMLで.logoと.textを交互に入れ替えて書かないほうがよいです。

今回は、.logoを60%、.textを40%の割合で、親要素の横幅目一杯(100%)まで表示することにします。

奇数番目のarticleの.logoと.textは逆順に表示したいので、CSSの擬似クラスnth-child(2n+1)を使って、flex-direction:row-reverse;を適用します。

article{
   display:flex;
 }
 .logo{
   width:60%;
   background:#e8e8e8;
   text-align:center;
 }
 .logo img{
   width:70px;
   height:auto;
   position:relative;
   top:50%;
   transform:translateY(-50%);
 }
 .text{
   box-sizing:border-box;
   width:40%;
   padding:5%;
   background:#cfcfcf;
   text-align:center;
 }
 article:nth-child(2n+1){
   flex-direction:row-reverse;
 }
 article:nth-child(2n+1) .logo{
   background:#f3f3f3;
 }
/* 2n+1は奇数番目のこと */

モバイル用に1カラムに変更するときは、
articleのflex-direction:column;で上からテキスト、画像の順番で表示する。

レスポンシブで書く場合のCSSはこんな感じ👇

article{
   display:flex;
   flex-direction:column;
 }
 .logo{
   box-sizing:border-box;
   padding:5%;
   background:#e8e8e8;
   text-align:center;
 }
 .logo img{
   width:70px;
   height:auto;
 }
 .text{
   box-sizing:border-box;
   width:100%;
   background:#cfcfcf;
   text-align:center;
 }

/* 以下PC用の表示 */
 @media screen and (min-width:640px){
   article{
     display:flex;
     flex-direction:row;
   }
   .logo{
     width:60%;
   }
   .logo img{
     position:relative;
     top:50%;
     transform:translateY(-50%);
   }
   .text{
     width:40%;
     padding:5%;
   }
   article:nth-child(2n+1){
     flex-direction:row-reverse;
   }
   article:nth-child(2n+1) .logo{
     background:#f3f3f3;
   }
 }

Demo

あえてちょっとずらしたタイル状のレイアウト

あえてちょっとずらしたタイル状のレイアウト

ぴしーっと揃ったレイアウトに比べて、楽しい感じや親近感のある雰囲気を演出できるちょっとずらしたレイアウトをflexboxで作ってみます。
とはいっても、普通にflexboxで並べてちょっとずらせば良いだけです。

今回のHTMLもリストで。

<ul>
  <li>Hello!</li>
  <li>Hey!</li>
  <li>Nice!</li>
  <li>Hello!</li>
  <li>Hey!</li>
  <li>Nice!</li>
</ul>

flexで並べるところまでは、一緒。今回は1列に3つのボックスを並べます。
CSSの擬似クラスで真ん中の列を下に50pxずらして、一番右の列を下に100pxずらします。

Hey!の2番目と5番目のボックスを選択するには、
3列のうちの2番目なので、3n + 2 番目のボックスになる。
Nice!のボックスは、 3n + 3 番目。
各ボックスを相対配置(position:relative;)でちょっとずらす。

相対配置はもともとの位置を基準にずらす量を設定するだけでよいのでとても便利です🙆

ul{
   display:flex;
   justify-content:space-evenly;
   flex-wrap:wrap;
   list-style:none;
   margin:0;
   padding:0;
 }
 li{
   width:28%;
   height:260px;
   margin:2% 0;
   position:relative;
   line-height:260px;
   background:#b6b6b6;
   text-align:center;
 }
 li:nth-child(3n+2){
   top:50px; /* Hey!のボックスを上から50pxずらす */
 }
 li:nth-child(3n+3){
   top:100px; /* Nice!のボックス上から100pxずらす */
 }

Demo

  • 縦方向中央に配置したいとき、align-items:center;が効かないときに確認すること
  • WordPressでカスタムタクソノミー一覧ページがリダイレクトされたときのメモ
  • HTMLのpicture要素でレスポンシブに対応した画像を読み込む
  • imgのsrcsetでレスポンシブで最適な画像を設定する方法
  • 2020年のバナナ
  • 要素を中央に表示したい!CSSでtext-align:center が効かないときに確認すること
  • スマホで100vhを使うと、アドレスバーの高さ分はみでてしまう
  • flexboxでページ全体のレイアウトを作ってみる
  • CSSのflexboxを使ってボックスをタイル状に並べる
  • CSSのflexboxを使っていろいろなナビゲーションをレイアウトしてみる
© b. All rights reserved.