レスポンシブ対応で変化するレイアウトにできるだけ最適な方法で対応したい

スタッフブログ

こんにちは、web制作事業部のハナフサです。
今回はwebサイトのレスポンシブ対応をしていた際に、掘り下げたい箇所があったので、そちらについて記事にまとめていこうと思います。

画面幅でレイアウトが変わる

今回の記事では、下の図を使って説明して行くので、まずはPC(パソコン)のレイアウトとSP(スマートフォン)のレイアウトで、どのような違いがあるのか見ていきます。

PCとSPのレイアウトの変更点としては、
・2カラムから1カラムになる。
・4番の緑箱が1番の赤箱と2番の青箱の間に入ってきて、HTML上の順番と違ったレイアウトになる。
の2点です。

HTML

今回は比較のためにPCとSPでHTMLは共通のものを使用し、CSSだけでレイアウトを変更していきたいと思います。

<!-- 全共通 -->
<!DOCTYPE html>
<html>
    <body>
        <ul class="container">
            <li class="item red1">1</li>
            <li class="item blue2">2</li>
            <li class="item yellow3">3</li>
            <li class="item green4">4</li>
        </ul>
    </body>
</html>

Flex box

これまで私はFlex boxを用いる前提でHTMLの構造を考えることが多かったので、使い慣れたFlex boxからやっていきます。

/*-- Flex box PC用 --*/
.container{
    display: flex;
    flex-direction: column;
    align-content: space-between;
    flex-wrap: wrap;
    width: 100%;
    height: 1000px;
    padding: 20px;
    box-sizing: border-box;
    list-style: none;
}
.item{
/*-- 説明用の数字を中央寄せするための指定 --*/
    display: flex;
    align-items: center;
    justify-content: center;
/*---------------------------------------*/
    width: calc( 50% - 10px );
    font-size: 45px;
    color: #fff;
}
.item.red1{
    background-color: #cc1f1f;
    margin-bottom: 20px;
    height: 250px;
}
.item.blue2{
    background-color: #241fcc;
    margin-bottom: 20px;
    height: 250px;
}
.item.yellow3{
    background-color: #cdc11f;
    height: 250px;
}
.item.green4{
    height: 790px;
    background-color: #1fcc43;
}

他にもやる方法はあると思いますが、とりあえず自分が考えた方法はこちらになります。まずは.containerdisplay:flexを指定します。そして、flex-direction: column;でデフォルトの横並びを縦並びにして、4番目の緑箱を次の列へ折り返させるために、.containerheightflex-wrap: wrap;を指定しました。

続いては、SP用に適応させるCSSを書いていきます。

/*-- Flex box SP用 --*/
@media(max-width: 420px){
    .container {
        flex-wrap: initial;
    }
    .item {
        width: 100%;
        margin-bottom: 20px;
    }
    .item.blue2{
        order: 3;
    }
    .item.yellow3{
        order: 4;
    }
    .item.green4{
        order: 2;
        height: 500px;
    }
}

こちらでは、要素を折り返すために指定していたflex-wrapを初期設定にして、折り返しをさせないようにしました。そして、変更点として挙げていた4番の緑箱を、1番の赤箱と2番の青箱の間に配置するためにorderで順番を指定し入れ替えています。

PCでは、.containerに対してflexの方向を変更したり、折り返しのための指定をしないといけない箇所がありました。.itemについては必要なmargin幅がそれぞれ違うので、個別に指定する必要がありました。

SPでは、.itemの表示位置の変更がorderに並び順の数値を指定するだけで簡単にできました。

gridレイアウト

次に試したのは、gridレイアウトです。

/*-- gridレイアウト PC用 --*/
.container{
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 20px;
    width: 100%;
    padding: 20px;
    box-sizing: border-box;
}
.item {
/*-- 説明用の数字を中央寄せするための指定 --*/
    display: flex;
    align-items: center;
    justify-content: center;
/*---------------------------------------*/
    height: 250px;
    font-size: 45px;
    color: #fff;
}
.item.red1 {
    grid-column: 1 / 2;
    grid-row: 1 / 2;
    background-color: #cc1f1f;
}
.item.blue2 {
    grid-column: 1 / 2;
    grid-row: 2 / 3;
    background-color: #241fcc;
}
.item.yellow3 {
    grid-column: 1 / 2;
    grid-row: 3 / 4;
    background-color: #cdc11f;
}
.item.green4 {
    grid-column: 2 / 3;
    grid-row: 1 / 4;
    background-color: #1fcc43;
    height: auto;
}

こちらに関してもやり方は他にもあると思いますが、とりあえず自分で考えた方法でやってみました。.containergrid-template-columnsでグリッドコンテナの列幅を設定。grid-gapを指定することで、.itemの余白を一括で指定しました。.itemには、grid-columnで列のセルやエリアを指定。grid-rowで行のセルやエリアを指定します。

続いては、SPに適応させるCSSを書いていきます。

/*-- gridレイアウト SP用 --*/
@media(max-width: 480px){
    .container {
        grid-template-columns: 1fr;
    }
    .item.red1{
        grid-row: 1 / 2;
    }
    .item.blue2{
        grid-row: 3 / 4;
    }
    .item.yellow3{
        grid-row: 4 / 5;
    }
    .item.green4{
        grid-column: 1 / 2;
        grid-row: 2 / 3;
        height: 500px;
    }
}

こちらでは、2カラムから1カラムにするために、grid-template-columns: 1fr;を指定しました。次に、.itemに対してそれぞれのセルやエリアの指定をし直しました。

gridレイアウトではPCとSP共に、グリッドコンテナの列の幅を指定さえすれば、グリッドに沿った任意の位置に.itemを配置することができたので、CSSでの記述が複雑でなくやりやすかったです。

SPでは、.itemの表示位置変更のために個別にgrid-columngrid-rowを指定し直す必要があり、Flex boxと比べると少し手間に感じました。

それぞれの特徴を理解し、使い分ける

Flex boxとgridレイアウトで組んでみて、今回のレイアウトでは、gridレイアウトの方が適していると感じました。上で書いたようにFlex boxの場合、要素を縦並びにしたあと、全体の高さを指定して折り返させるというやり方に少し複雑な印象を受けましたが、gridでは直感的といいますか、複雑なことを考えることなく見た目通り考えたものをそのまま配置できた気がします。

grid-gapに関しても.containerに指定することで一括で.itemの余白を空けることができ、便利に感じました。個別に余白を指定したい場合は、そのままmarginを指定すれば良いので、さまざまなデザインへの対応がしやすいと感じました。

今回はFlex boxとgridレイアウトを使って、レイアウトの実装をやってみましたが、その他の方法でも同じようなレイアウトが作れる場合もあると思います。大切なのは、プロパティーの特徴を理解したうえで、どのやり方が最適かを考えて選択していくことだと思うので、多くの選択肢を持てるよう、引き出しを増やしていきたいと思います。