【CSS】Flexboxを使って実用的なレイアウトを実装

WEB制作・開発実例・コラム
2018.02.28
2018.03.01

みなさんは横並びのレイアウトのスタイルはどう書かれていますか?
float、display:inline-block、display:table-cell、そしてdisplay:flexと、シーンに合わせて使い分けていますか?
今回はfloatに代わる横並びスタイルの記述方法として注目され、その利便性が定着しつつあるFlexboxについて実用的なレイアウトサンプルを交えて使い方を解説したいと思います。

Flexboxの基本

親要素にdisplay:flexをつけるだけです。こうすることで親要素はFlexboxコンテナーになり、 そして子要素は自動的にFlexboxアイテムになります。これが基本になります。

プロパティーについて

このFlexboxコンテナーFlexboxアイテムにはそれぞれに指定出来るいくつかのプロパティーがあります。
今回は実用的なレイアウトをメインにご紹介したいのでプロパティーについては割愛させていただきます。

プロパティーを理解するのにわかりやすいサイトもあるので、是非チェックしてみてください!

おすすめのサイト

Flexboxを使った実用的なデザインサンプル

プロパティーを割愛させていただいたところで早速サンプルを作っていきましょう。

sample1-フォトギャラリーを作る

Instagramで見慣れているような3カラム正方形のフォトギャラリーをflexboxを使って実装します。

DEMO

まずはhtmlです。

<div class="photogallery">
           <div class="photo">
            <div class="inner">
                <img src="./images/s_FH000019.JPG" alt="">
            </div>
        </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000023.JPG" alt="">
               </div>
           </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000024.JPG" alt="">
               </div>
           </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000027.JPG" alt="">
               </div>
           </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000030.JPG" alt="">
               </div>
           </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000031.JPG" alt="">
               </div>
           </div>
           <div class="photo">
               <div class="inner">
                   <img src="./images/s_FH000032.JPG" alt="">
               </div>
           </div>
        </div>

次にcssです。親要素である.photogalleryにdisplay:flexをつけます。 そして子要素の.photoはFlexboxアイテムになります。 縦に並んでいた画像が横並びになったかと思います。

.photogallery{
            display: flex;
        }

アイテムの折り返しを指定するflex-wrap

このままだと画像は1行に並列されるので、flex-wrapを使って画面内でアイテム要素を折り返すようにします。

.photogallery{
            display: flex;
            flex-wrap: wrap;
        }

これはとてもシンプルなFlexboxの使い方ですね。
今回はInstagram風という事で、下記のスタイルも合わせて実装しているのでそちらのcssも合わせてご参考ください!

  • レスポンシブ時でも縦横比を保ち3カラムのままボックス要素を拡縮させる。
  • 写真をセンターで1:1の比率にトリミング
/*sample1*/
        .photogallery{
            display: flex;
            display: -webkit-flex;
            flex-wrap: wrap;
            -webkit-flex-wrap: wrap;
        }
        .photo {
            position: relative;
            width: 31%;
            height: auto;
            margin: 1%;
            overflow: hidden;
        }
        .photo:before {
            content: "";
            display: block;
            padding-top: 100%;
        }
        .inner {
            position: absolute;
            top: 0; left: 0;
            width: 100%;
            height: 100%;
        }
        .inner img{
            position: absolute;
            top: 50%;
            left: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
            width: auto;
            height: 100%;
        }

sample2-メディアオブジェクトを作る

左に画像、右にテキストといったようなレイアウト、よく使いますよね。これもflexboxで実装するととても簡単です!

DEMO

まずはhtmlです

<div class="profile_card">
            <div class="card_photo">
                <div class="card_photo_img"><img src="./images/sample2_img1.jpg" class="hoverZoomLink"></div>
                <h1>Peco Taro</h1>
                <h2>株式会社ペコプラ</h2>
            </div>
            <div class="profile_bio">
                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis,</p>
                <ul class="profile_sociallinks">
                    <li>
                        <a target="_blank" href="https://www.facebook.com/">
                            <i class="fa fa-facebook"></i>
                        </a>
                    </li>
                    <li>
                        <a target="_blank" href="https://twitter.com/">
                            <i class="fa fa-twitter"></i>
                        </a>
                    </li>
                    <li>
                        <a target="_blank" href="#">
                            <i class="fa fa-google-plus"></i>
                        </a>
                    </li>
                    <li>
                        <a target="_blank" href="#">
                            <i class="fa fa-instagram"></i>
                        </a>
                    </li>
                </ul>
            </div>
        </div>

h2の「株式会社ペコプラ」までを左側に。テキストとSNSシェアボタンは右側に配置します。

.profile_card{
            display: flex;
        }

垂直方向の揃え方を指定するalign-items

次に垂直方向に中央で揃えたいので、align-itemscenterを指定。

.profile_card{
            display: flex;
            align-items: center
        }

水平方向の揃え方を指定するjustify-content

SNSシェアボタンも横並びにしたいので.profile_sociallinksにdisplay: flex;を指定します。またセンターにする為に平方向の揃え方を指定するjustify-contentcenterを指定すれば完成です。

レスポンシブ対応も簡単です!メディアクエリでブレイクポイントを指定し、flexコンテナである.profile_cardのdisplayプロパティをblockにすればOKです。

@media screen and (max-width: 700px) {
            .profile_card{
                 display: block;
            }
        }

sample3-高さの異なるメディアオブジェクトを並べる

Flexboxの便利な点の一つは高さを揃えるという事じゃないでしょうか。
sample2で作成したメディアオブジェクトをそれぞれ高さを変え、横に並べたいと思います。

DEMO

今までのマークアップ同様、親要素にdisplay: flex;を記述し横並びにします。
そうすると高さの異なる3つの子要素が同じ高さになって横並びになると思います。これはsample2でも出てきたalign-itemsがデフォルトの状態であるstretchだからです。

ここで子要素内のSNSシェアボタンを下揃えにしたい!なんていうのも簡単です。
各子要素内でSNSボタンとそれ以外の要素を分けて、flex-direction: column;(縦配置なので見た目はそのまま)。
主軸に対して端揃えになるjustify-content: space-between;を指定します。ここでは端揃え=上下揃えです。
今までposition: absolute;なんかで無理やり位置を指定していたmoreボタンやなんかにもガンガン使えますね!

sample4-価格表示のグリッドデザインを作る

レスポンシブ時には要素の順番を入れ替えたい!なんていう事を叶えてくれるのもFlexboxの魅力のひとつです!
下記のような料金表を実装していきましょう。

DEMO

まずはhtmlです。

<ul class="pricecards">
               <li class="pricecard free">
                   <h3>Free</h3>
                   <h4>0</h4>
                   <div>yen/月</div>
                   <p>freeプランのテキストが入ります。freeプランのテキストが入ります。freeプランのテキストが入ります。</p>
                   <a href="">申し込み</a>
               </li>
               <li class="pricecard premium">
                   <h3>Premium</h3>
                   <h4>2,980</h4>
                   <div>yen/月</div>
                   <p>Premiumプランのテキストが入ります。Premiumプランのテキストが入ります。Premiumプランのテキストが入ります。</p>
                   <a href="">申し込み</a>
               </li>
               <li class="pricecard standard">
                   <h3>Standard</h3>
                   <h4>1,200</h4>
                   <div>yen/月</div>
                   <p>standardプランのテキストが入ります。standardプランのテキストが入ります。standardプランのテキストが入ります。</p>
                   <a href="">申し込み</a>
               </li>
           </ul>

そして例の如く包括しているulタグに.pricecardsを付けてdisplay: flex;を指定します。 flexアイテムである.pricecardには下記のようにflex-basisで33%の幅を設定。ここではまとめてflexで記述します。
またPremiumプランを目立たせたいのでpaddingで高さを出し、align-items:にcenterを指定して上下中央揃えにする事で、他のプランより大きく見えるようにしました。

.pricecards{
            display: flex;
            display: -webkit-flex;
            flex-wrap: wrap;
            -webkit-flex-wrap: wrap;
            align-items: center;
            -webkit-align-items: center;
            justify-content: center;
            -webkit-justify-content: center;
        }
        .pricecard{
            flex: 0 0 33%;
            text-align: center;
            border: 1px solid #eee;
            padding-bottom: 1rem;
            box-sizing: border-box;

        }
        .pricecard h3{
            background: #a2bc10;
            color: #fff;
            padding: 10px;
            margin: 0;
        }
        .pricecard.premium{
            border: 3px solid #06c7ea;
            padding-bottom: 3rem
        }
        .pricecard.premium h3{
            background: #06c7ea;
            color: #fff;
            padding: 10px;
            margin: 0;
        }
        .pricecard h4{
            font-size: 300%;
            margin: 0 auto;
            padding: 1rem 0 0;
        }
        .pricecard.premium h4 {
            padding: 20px;
        }
        .pricecard p{
            margin: 0;
            padding: 1rem;
            text-align: left;
        }
        .pricecard a{
            padding: 10px 40px;
            background: #fb5859;
            color: #fff;
            text-decoration: none;
            border-radius: 3px;
            display: inline-block;
        }

レスポンシブは親要素のflex-directionwcolumnにして縦並びにすれば一発なのですが、
一押しプランの「Premiun」をスマホ閲覧時は上から価格順に表示させたいといった場合があります。
こんな時はorderプロパティが便利!順番が入れ替えられます。

@media screen and (max-width: 700px) {
.pricecards{
flex-direction: column;
}
.pricecard.premium{
order: 1;}
}

まとめ

いかがでしたか?Flexboxについて実用的なレイアウトサンプルをいくつか作成していきました。
今まで地味に苦労していた横並び要素の高さを揃えるだとか、上下左右センター揃えといったマークアップが、Flexboxでは簡単に実装できます!
わたし自身は大まかなレイアウトなどには未だにfloatを使っていたりするのですが、モバイルフレンドリーな時代のサイトをよりフレキシブルにマークアップしていけるよう、さらにFlexbox使いこなしていきたいと思います!

コラム

最新コラム

人気コラム

ご質問やご相談などお気軽にお問い合わせください。

お電話でのお問い合わせはこちら

03-5829-9912

受付時間:平日10:00~19:00(土・日・祝日を除く)