TECHNICAL BLOG

2021/2/25 # フロントエンド # 入門 # CSS # HTML 2021/2 CSSレイアウト設計で抑えるべきコツ

HTML/CSSで文字サイズや背景色などの装飾をするのは比較的簡単ですが、レイアウトを作るのは慣れていないと難しいですよね。僕もはじめのうちはレイアウトを作っていくのがとても苦手でした。

そこで今回は、レイアウトを作るときに抑えておくべきコツなどを紹介したいと思います。

Flexbox

まずはじめに、レイアウトを組むときに必要なFlexboxについて、基本だけ紹介しておきます。

Flexbox(Flexible Box Layout Module)とは、フレキシブル(柔軟)にレイアウトを組むことができるCSSの機能のことです。

Flexboxは、親要素(フレックスコンテナ)の中で、子要素(フレックスアイテム)をどのように配置するかを指定します。
以下の図で、一番外側の枠が親、内側にある小さい四角が子になります。

Flexboxの概念

この親と子の構造をHTMLで実現すると以下になります。

<div class="flex-container">
    <div class="flex-item"></div>
    <div class="flex-item"></div>
    <div class="flex-item"></div>
</div>

見ての通り、入れ子構造にするだけです。ただし、divタグはブロック要素なので、このままだと縦に積まれてしまいます(ブロック要素については 『2018/4 CSSとHTML レイアウト入門』参照)。

Flexboxなしの場合

これを最初の画像のように横並びするには、親要素に以下を指定します。

.flex-container{
    display: flex;   /* ← これを指定する */
    max-width: 420px;
    margin: 2rem;
    border: 3px solid #287AA3;
    background-color: #DCEDF3;
}
.flex-item{
    margin: 20px;
    background-color: #3398CC;
    width: 100px;
    height: 100px;
}

Flexboxはレイアウトに関するプロパティを親・子それぞれに指定することができます。ざっくりと説明すると、親要素には子要素の並べ方、子要素には、子要素(自分自身)の表示の仕方に関わるプロパティを指定できます。

・親に指定するプロパティの例

flex-direction: 並べ方(横か縦)と向き (通常か逆向き)
justify-content: 水平方向の配置
align-items: 垂直方向の配置

・子に指定するプロパティの例

・flex-grow: 子要素の伸びる比率
・flex-shrink: 子要素の縮む比率

ただし、Flexboxを使う際は親要素に必ずdisplay: flexを指定する必要がありますので、注意してください。

Flexboxの各プロパティについての詳しい説明は以下のサイトがとても参考になります。

『日本語対応!CSS Flexboxのチートシートを作ったので配布します』
https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet

DOM構造とデザインの四原則

Flexboxが使えても、デザインに即したDOMの構造(HTMLの書き方)がわからなければレイアウトを作ることはできません。レイアウトに適したHTMLの書き方がわからない人は、まずはデザインの四原則を意識してみましょう。

デザインの四原則とは、近接、整列、反復、対比のことです。この四原則を守ったデザインは、見やすくてわかりやすいデザインになります。

ここではレイアウトと特に関わりの深い近接と整列について簡単に触れておきます。

近接

関連度が高いものは近くに、低いものは離れて配置する、という原則です。
要素と要素の位置関係を意識することでグループを作ることができ、読み手に情報をわかりやすく伝えることができます。

具体的な例を見てみましょう。

近接の原則

左のほうは全体的にギュッと集まっていて、位置関係が掴みにくくなっています。この場合は、情報の関連度をもとに余白で位置関係を整理し、グループ化することにより情報が理解しやすくなります。

整列

要素はバラバラに配置せず、見えない線を感じられるように配置を揃える、という原則です。スッキリとしたデザインになり、情報が読みやすくなります。

整列の原則

上の図の左右を見比べてみてください。左のほうは写真と文字の位置、文字の並びがバラバラです。右のほうは配置が揃っているので、左の図よりも見やすくなっています。

DOM構築のコツ

ここからが本題です。ここまでで説明したFlebox、近接・整列の原則を使って以下のレイアウトを作っていきます。
最初は細かいパーツに着目せず、大きなパーツ(レイアウトのDOM)からやるのがコツです。

作成するレイアウト例

①整列でグループ分け

縦・横の位置が揃っているところに線を引きます。

デザインに線を引く

他にも整列しているところはありますが、最初は大きく整列しているところだけで大丈夫です。

縦方向は赤色の実線の内側に全てのコンテンツが収まっているので、ひとつの大きなグループと見なすことができます。
横方向は青色の実線で上下に分けることができるので、赤色のグループの中に、グループが上下に2つできていることがわかります。

これをHTMLで書くとこのようになります。

<body>
    <div class="wrapper">
        <div class="header">
            <!-- メイン画像やタイトルなど -->
        </div>
        <div class="main">
            <!-- サイドバー、記事本文が入る -->
        </div>
    </div>
</body>

赤色のグループは<div class="wrapper">が該当します。青色のグループは赤色のグループの中で隣同士で存在するので、<div class="header"><div class="main">のように兄弟要素として書きます。

ここで一度スタイルを当てましょう。

.wrapper {
    width: 100%;
    max-width: 1100px; /* 全体の最大幅 */
    margin: 0 auto;    /* 中央寄せ */
}
.header {
    width: 100%;
    margin-bottom: 3rem; /* ヘッダーとメイン部分の余白 */
}
.main {
    width: 100%;
}
/* 以下は説明用 */
.header {
    height: 500px;
    background-color: pink;
}
.main {
    height: 800px;
    background-color: lightblue;
}

ヘッダー・メイン部分のレイアウト作成

わかりやすいように高さと背景色を設定しています。以上で赤線のグループ、青線のグループのレイアウトが完成しました。
青いグループの方はまだ整列の観点でグループ分けできそうなところがありますね。

更に線を引いてグループ分け

この3つのグループも、大きいグループの中に隣同士で存在しているので、<div class="main">の中に兄弟要素として書いてあげます。

<div class="main">
    <div class="sidebar">
        <!-- カテゴリーなど -->
    </div>
    <div class="content">
        <!-- 記事本文 -->
    </div>
    <div class="sidebar">
        <!-- プロフィール -->
    </div>
</div>

ただし、<div>はブロック要素のため、このままだと縦に積まれてしまいます。ここで、最初に説明したFlexboxの登場です。親である<div class="main">display: flexを設定してあげましょう。

.main {
    width: 100%;
    display: flex;
}
.sidebar {
    width: 180px;
}
.content {
    flex-grow: 1; /* 伸びる率の設定 */
    margin: 0 2.5rem; /* サイドバーとの余白 */
}
/* 以下説明用 */
.sidebar, .content {
    height: 800px;
    background-color: lightblue;
}

メイン部分のレイアウト作り込み

Flexboxを使うことにより各グループが横並びになっていますね。これで大きなレイアウトの作り込みは終わりました。このように、大きいものから小さいものへと少しずつ作っていけば、難しく見えるレイアウトも簡単に作っていくことができます。

②近接でグループ分け

近接の観点で、今度はヘッダー部分をグループ分けしていきます。近接を見る前に、画像と文字部分でグループを分けておきます。
次に、近いもの同士は同じグループ、離れているものは別グループとして四角で囲います。

近接でグループ分け

タイトルとナビゲーション部分で2つのグループができていることがわかります。ではここまでをHTMLで書いてみましょう。

<div class="header">
    <div><!-- 画像部分 -->
        <img src="./img/main-image.png">
    </div>
    <div class="header-bar"><!-- 文字部分 -->
        <div class="title">
            <img src="./img/title.png">
        <div>
        <div>
            <div class="nav">
                トップなど
            </div>
        </div>
    <div>
</div>

文字部分のタイトルとナビゲーションは同じグループの中で別々のグループとして存在しているので、兄弟要素として書いています。
しかし、<div>タグはブロック要素であり、このままだと横に並びません。Flexboxを使って横並びにしましょう。

img {
    width: 100%;
}
.header-bar {
    display: flex;
}
.title {
    max-width: 500px;
}

ヘッダーにFlexboxを適用

display: flexを指定して横並びにしました。しかし、タイトルとナビゲーションがすぐ隣合わせになっています。また、縦方向の並びもずれています。そのため、Flexboxの並べ方に関するプロパティを使って、デザインを整えます。

img {
    width: 100%;
}
.header-bar {
    display: flex;
    justify-content: space-between; /* 横方向の配置 */
    align-items: flex-end           /* 縦方向の配置 */
}
.title {
    max-width: 500px;
}
.title img {
    vertical-align: top;  /* 画像の下にできる余白を打ち消す */
}

ヘッダーのレイアウト完成

横方向の配置も縦方向の配置もデザイン通りになりました。justify-content: space-betweenを指定すると、端から端まで等間隔に要素を配置します。align-items: flex-endは縦方向の配置を下にします。

③細かく部品に分ける

レイアウトの対応が終わったら細かく部品に分けていきましょう。

細かく部品に分ける

流れとしてはこれまでと同じです。これ以上分けられないレベルでグループ分けをして、親子・兄弟関係を意識しながらそれぞれ<div>などで囲います。HTMLが書けたら各部品にスタイルをあてて完成です。

今回レイアウト設計で少し紹介したデザインの四原則は、デザイン作りには欠かせないとても大事なルールです。良いデザインを自分でも作れるようになりたいという人は、以下の本に詳しく解説されていますので、一読をお勧めします。

『ノンデザイナーズ・デザインブック』
https://www.amazon.co.jp/-/jp/Robin-Williams/dp/4839955557/

Tips

最後に、本記事ではあまり触れなかったポイントなどをリストでまとめておきます。

  • ブロック要素なのか、インライン要素なのかを意識して使う
  • 親子関係、兄弟関係を意識してHTML/CSSを書く
  • marginは外側の余白、paddingは内側の余白
  • <br />タグを余白のために使わない
  • デフォルトCSS

デフォルトCSSに関して補足しておくと、<ul><h1>などのタグにはあらかじめ余白や文字サイズなどのスタイルが適用されています。
詳しくは以下を参考にしていただければと思います。

『デフォルトスタイルシートとリセットCSS』
https://www.kenschool.jp/blog/?p=3709

まとめ

レイアウトを組むときは、DOMをどのように構築するかがとても大事です。慣れればデザインを見るだけでスラスラとDOMを構築できますが、慣れないうちは整列・近接のルールを意識しながらレイアウトを作っていきましょう。